使用 jQuery / JavaScript (ASP.NET) 将下拉链接的父列表项设置为活动状态

Posted

技术标签:

【中文标题】使用 jQuery / JavaScript (ASP.NET) 将下拉链接的父列表项设置为活动状态【英文标题】:Set parent list item of dropdown link to active with jQuery / JavaScript (ASP.NET) 【发布时间】:2019-07-24 07:48:42 【问题描述】:

这是我的菜单

<ul class="sidebar-menu" id="navigation-menu">
    <li class="active"><a class="nav-link" href="/"><i class="fas fa-home"></i><span>Home Page</span></a></li>
    <li class="nav-item dropdown">
        <a href="#" class="nav-link has-dropdown"><i class="fas fa-cog"></i><span>Configuration</span></a>
        <ul class="dropdown-menu">
            <li><a class="nav-link" href="/Configuration/AccountCodes">Account Codes</a></li>
            <li><a class="nav-link" href="/Configuration/Branches">Branches</a></li>
        </ul>
     </li>
     <li class="nav-item dropdown">
         <a href="#" class="nav-link has-dropdown"><i class="fas fa-person-booth"></i><span>Directory</span></a>
         <ul class="dropdown-menu">
             <li><a class="nav-link" href="/Directory/Users?Role=Administrator">Administrators</a></li>
             <li><a class="nav-link" href="/Directory/Users?Role=Manager">Managers</a></li>
             <li><a class="nav-link" href="/Directory/Users?Role=Agent">Agents</a></li>
         </ul>
     </li>
</ul>

这是我的 Jquery,当我选择配置下拉菜单下的 AccountCodes 时,它应该只将父列表项设置为活动状态。但是,目录父级也设置为活动。我不知道如何直接选择它。

另外,由于我的 URL 结构,我无法继续使用 endWith。是否有基于 url 设置活动类的替代方法?目前,如果我选择 AccountCodes 或 Branches,它会正确地将 Configuration 下拉项设置为活动状态。但是,如果我选择代理,则根本不会选择任何内容,因为它的 url 以 ?Agent 而不是 Users 结尾

<script>
    $(document).ready(function () 
        var current = location.pathname;
        console.log(current);
        $("#navigation-menu a").each(function () 
            var $this = $(this);
            console.log($this.attr('href'));
            if ($this.attr('href').endsWith(current)) 
                console.log($this.parent());
                $this.parent().addClass('active');
                console.log("matched");
            
        );
        if ($(".dropdown-menu li").hasClass("active")) 
            console.log("Yes");
            var $this = $(this);
            $(".dropdown-menu li").prev().parent().parent().addClass('active');
            console.log($(".dropdown-menu li").closest(".nav-item dropdown"));
        
    );
</script>

【问题讨论】:

调试的时候current的值是多少? $this.attr('href') 的值是多少? $this.attr('href').indexOf(current) 的结果是什么? 当我在 AB 页面上时,URL 是 localhost.com:5888/Configuration/AC,控制台显示 Configuration/AC。这就是 current 的值。 您熟悉如何使用浏览器的调试工具吗?因为现在是使用它们的时候了。您可以在代码中放置断点以暂停该行的执行,然后在暂停时使用控制台观察值和操作结果。当您这样做时...current 的值是多少? $this.attr('href') 的值是多少? $this.attr('href').indexOf(current) 的结果是什么? 我得到了这些结果 current = /Configuration/AccountCodes thisvalue = w.fn.init [a.nav-link] indexOfResult = -1 是的。不过我会把它改成 html,这样更容易阅读。 【参考方案1】:

有两种方法可以仅将父链接标记为活动。

1。使用 jQuery

这样做的好处是可以兼容任何后端平台。

<script>
    $(document).ready(function () 
        var current = location.pathname;
        console.log(current);
        $("#navigation-menu a").each(function () 
            var $this = $(this);
            var link = $this.attr('href');
            console.log(link);

            // Remove the query string parameters by finding their starting position
            var indexOfQueryString = link.lastIndexOf("?");
            link = link.substring(0, indexOfQueryString);

            if (link.endsWith(current)) 
                console.log("matched");
                if ($this.parent().parent().hasClass('.dropdown-menu')) 
                    var parentLink = $this.closest('.dropdown');
                    console.log("Setting parent link as active:", parentLink);
                    // Find the closest parent link and add active class
                    parentLink.addClass('active');
                 else 
                    console.log("Setting link as active: ", $this.parent());
                    $this.parent().addClass('active');
                
            
        );
    );
</script>

在这种情况下,正如您所提到的,您遇到了链接中存在?Agent 的问题——这就是我们所说的查询字符串参数,我们可以通过搜索未编码的问号。解决方案中已经考虑了这一点。

2。使用 ASP.NET MVC

在后端执行此操作会更加健壮,并且如果用户禁用 javascript,此功能仍然可以在您的网站中使用。不过,正如您可能已经猜到的那样,缺点是它依赖于平台。

有很多方法可以解决这个问题。对于您的特定用例,由于您的下拉链接通过area 与父级相关联,因此我调整了another SO answer 以涵盖您的特定用例:

public static string IsSelected(this HtmlHelper html, string area = "", string cssClass = "active")

    ViewContext viewContext = html.ViewContext;
    RouteValueDictionary routeValues = viewContext.RouteData.Values;
    string currentArea = routeValues["area"] as string;

    return area.Equals(currentArea) ? cssClass : String.Empty;

那就这样用吧:

<ul class="sidebar-menu" id="navigation-menu">
    <li><a asp-area="" asp-controller="Home" asp-action="Index" class="nav-link"><i class="fas fa-home"></i><span>Home
                Page</span></a></li>
    <li class="nav-item dropdown @Html.IsSelected(area: "Configuration")">
        <a href="#" class="nav-link has-dropdown"><i class="fas fa-cog"></i><span>Configuration</span></a>
        <ul class="dropdown-menu">
            <li><a asp-area="Configuration" asp-controller="AccountCodes" asp-action="Index" class="nav-link">Account
                    Codes</a></li>
            <li><a asp-area="Configuration" asp-controller="Branches" asp-action="Index" class="nav-link">Branches</a>
            </li>
        </ul>
    </li>
    <li class="nav-item dropdown  @Html.IsSelected(area: "Directory")">
        <a href="#" class="nav-link has-dropdown"><i class="fas fa-person-booth"></i><span>Directory</span></a>
        <ul class="dropdown-menu">
            <li><a asp-area="Directory" asp-controller="Users" asp-action="Index" asp-route-Role="Administrator"
                    class="nav-link">Administrators</a></li>
            <li><a asp-area="Directory" asp-controller="Users" asp-action="Index" asp-route-Role="Manager"
                    class="nav-link">Managers</a></li>
            <li><a asp-area="Directory" asp-controller="Users" asp-action="Index" asp-route-Role="Agent"
                    class="nav-link">Agents</a></li>
        </ul>
    </li>
</ul>

这对您有好处吗,请确保也为其他链接的答案投票。

【讨论】:

我更喜欢你的第二个建议。但是,看起来它直接设置了列表项。它也适用于父列表项吗? 是的,@JianYA。由于您的下拉链接按区域分组,因此我添加了将使用它的代码。让我们知道这是怎么回事。 @JianYA 你也可以考虑在你的帖子中插入以前版本的 HTML,这样其他人就可以从那里遵循这个答案。

以上是关于使用 jQuery / JavaScript (ASP.NET) 将下拉链接的父列表项设置为活动状态的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript之jQuery-7 jQuery 使用插件(使用插件日历插件表单验证插件)

php课程---JavaScript与Jquery的区别(转)

jQuery 第一阶段 学习使用总结

javascript 学习小结 jQuery封装ajax尝试 by FungLeo

JavaScript之jQuery-2 jQuery选择器(jQuery选择器基本选择器层次选择器过滤选择器表单选择器)

使用 javascript 或 jQuery 隐藏所有带有与数字“0”或自定义值匹配的文本或 innerHTML 的“a”元素