4

我在 _Layout.cshtml 中有这个菜单:

<td class="MenuStructure">
    <ul id="menu">
        <li>@Html.ActionLink("First Page", "Page1Action", "Main")</li>
        <li>@Html.ActionLink("Second Page", "Page2Action", "Main")</li>
        <li>@Html.ActionLink("Third Page", "Page3Action", "Second")</li>
    </ul>
</td>

单击其中一个操作链接时,我想将包含它的 <li> 的类设置为“已选择”,将其他 <li> 元素的类设置为“”。

这有效:

    <script type="text/javascript">
        $(document).ready(function () {
        var selMenu = '@ViewBag.SelectedMenu';
            if (selMenu == "page1") {
                $("#page1").attr('class', 'selected');
                $("#page2").attr('class', '');
                $("#page3").attr('class', '');
            }
            if (selMenu == "page2") {
                $("#page1").attr('class', '');
                $("#page2").attr('class', 'selected');
                $("#page3").attr('class', '');
            }
        });
    </script>

但它非常丑陋。有人可以告诉我一个更优雅的方法吗?

4

2 回答 2

2

如果您将单击事件处理程序添加到a元素组,则可以轻松地将类添加到单击的元素li并为所有兄弟元素删除它,无论有多少。这消除了对 if 语句和attr每个li.

这是一个示例:

http://jsfiddle.net/JjBgm/4/

标记:

<ul id="menu">
    <li><a href="#">one</a></li>
    <li><a href="#">two</a></li>
    <li><a href="#">three</a></li>
</ul>

jQuery:

$(document).ready(function() {

    $('#menu li a').click(function() {
        $(this).parent().addClass('selected').siblings().removeClass('selected');
    });

});

您显然必须使用 MVC 根据您的需要修改这种方法,但是这个概念应该有效。

编辑:因为你提到有一个往返所涉及的服务器上面可能无法正常工作。在这种情况下,您可以根据所选菜单构建客户端 id 并从那里控制类。

$(document).ready(function () {
    var selMenu = '@ViewBag.SelectedMenu';
    $("#" + selMenu).addClass('selected').siblings().removeClass('selected');
});

这是假设#page1,#page2<li>在服务器处理后没有看到生成的标记的情况下引用元素。

如果#page1引用<a>标签,那么您的声明将是:

$("#" + selMenu).parent().addClass('selected').siblings().removeClass('selected');

当然未经测试。重点是动态构建您的选择器,然后根据需要使用兄弟选择器和父选择器来清除类。干净多了。

于 2012-05-10T17:34:29.927 回答
0

我假设这是您网站的主要导航,即使您没有执行确切的操作,您也希望保持顶部菜单“选中”(例如,链接进入列表,但随后您进入“编辑”页等)。

有两种方法可以做到这一点。一种是在 viewbag 中放置一个属性,然后在渲染时在 _layout.cshtml 文件中检查该属性。

// in controller Action method
ViewBag.SelectedMenu = "first"
// in view
<li class="@((ViewBag.SelectedMenu == "first") ? "selected-class" : "")">first link</li>

第二种方式(我们使用的)是使用站点地图包(从 NuGet 安装)。然后您在根目录中编辑您的站点地图文件,并将所有链接放在那里(即使是您不直接用于导航的链接)。然后,您可以为您呈现控件<ul><li>'s。它主要输出与您现在拥有的相同的 html,因此 css 应该仍然可以工作。

  • 所有菜单内容集中在一个地方
  • 站点地图尊重 [authorize] 属性或其他过滤器,仅隐藏登录链接
  • 可以隐藏/显示菜单中可能不存在的节点(重新映射的 url 等)
  • 许多其他不错的小功能

Mvc.sitemap文件:

<mvcSiteMapNode title="Home" controller="Home" action="Index">
<mvcSiteMapNode title="Get a car" controller="Cars" action="Buy"/>
    <mvcSiteMapNode title="Reports" controller="Report" action="AllReports">
      <mvcSiteMapNode title="" controller="Report" action="ViewMPG"/>
    </mvcSiteMapNode>
</mvcSiteMapNode>

然后,在您的_Layout.cshtml文件中:

<td class="MenuStructure">
    <!-- one level menu starting at top (home), including the "home" link -->
    @Html.MvcSiteMap().Menu(0, true, true, 1)
</td>

然后修改Views\Shared\MenuHelperModel.cshtml改变样式:

<ul id="menu">
    @foreach (var node in Model.Nodes)
    {
        var show = node.IsInCurrentPath && (!node.IsRootNode || node.IsCurrentNode);
        var cls = show ?  "selected" : ""; 
        <li class="@cls">@Html.DisplayFor(m => node)</li>
    }
</ul>
于 2012-05-10T18:01:13.923 回答