简体   繁体   English

在 ASP.Net MVC 5 应用程序中访问页面时如何保持活动菜单项突出显示?

[英]How to keep the active menu item highlighted when visiting pages in ASP.Net MVC 5 application?

So, I have one ASP.Net MVC 5 application.所以,我有一个 ASP.Net MVC 5 应用程序。 In that one of page hasfour menu items.在那一页中有四个菜单项。 When page loads first menu item is selected by default (so it should be highlighted as soon as the page loads).当页面加载时,默认选择第一个菜单项(因此它应该在页面加载后立即突出显示)。 And now as soon as user clicks on any other menu, that other menu should be in highlighted stage, so that user knows which menu he is currently on.现在只要用户点击任何其他菜单,该其他菜单就应该处于突出显示的阶段,以便用户知道他当前在哪个菜单上。 Below is my attempt:以下是我的尝试:

My thinking:我的想法:

a. a. add a click event on the ul tag.在 ul 标签上添加一个点击事件。

b.when clicked find "active" class inside ul tag and remove it.单击时在 ul 标签中找到“活动”类并将其删除。

c. C. now add active class to the source of click event (which means the li tag on which user clicked).现在将活动类添加到点击事件的来源(这意味着用户点击的 li 标签)。

Issue:问题:

The selected/clicked menu gets highlighted for a second, and then automatically first menu gets highlighted.选定/单击的菜单会突出显示一秒钟,然后自动突出显示第一个菜单。 So as soon as the whole page corresponding to the newly clicked menu item reloads the first menu item gets highlighted back.因此,只要与新单击的菜单项对应的整个页面重新加载,第一个菜单项就会重新突出显示。

My Attempt我的尝试

PS: This is a partial View, And all redirects will load this partial view afresh . PS:这是一个局部视图,所有重定向都会重新加载这个局部视图。

@if (Request.IsAuthenticated)
{
    <ul style="list-style-type:none;">
        <li class="active setBtnMargin">
            <a href="@Url.Action("Index", "Resume")" class="btn btn-block">My Resume </a>
        </li>
        <li class="setBtnMargin">
            <a href="@Url.Action("Index", "CoverLetter")" class="btn btn-block">My Cover Letter </a>
        </li>
        <li class="setBtnMargin">
            <a href="@Url.Action("Index", "Home")" class="btn btn-block">My Account </a>
        </li>
        <li class="setBtnMargin">
            <a href="@Url.Action("Index", "Home")" class="btn  btn-block">Get Rewards </a>
        </li>
    </ul>
}

<script>
// ATTEMPT 1
    $("ul").on("click", "li", function () {
        $('ul li').removeAttr('active');
        $(this).addClass('active');
    });

// ATTEMPT 2
    //$("li").click(function () {
    //    //$("ul li").removeClass("active");
    //    $(this).addClass("active");
    //});
</script>

EDIT 1编辑 1

So the problem is as the page gets redirected.所以问题在于页面被重定向。 The active tag again gets appened to the first menu item when entire DOM gets reloaded because all the landing pages use the same partial view .当整个 DOM 重新加载时,活动标记再次附加到第一个菜单项,因为所有登录页面都使用相同的部分视图

Everytime you click on a link, it does a page redirect, and it doesn't matter what changes you've made with jQuery, it always fetch this partial view, and in this partial view, you have active class on the first link, that is why it always highlights the first link.每次单击链接时,它都会进行页面重定向,并且无论您使用 jQuery 进行了哪些更改,它始终会获取此部分视图,并且在此部分视图中,您在第一个链接上有活动类,这就是为什么它总是突出显示第一个链接。

What you have to do is write an HtmlHelper that will add the class "active" to current link on each page load.您需要做的是编写一个 HtmlHelper,它将在每个页面加载时将“active”类添加到当前链接。 Create a folder called Helpers under your project and add a custom HtmlHelper class.在您的项目下创建一个名为 Helpers 的文件夹并添加一个自定义 HtmlHelper 类。

using System;
using System.Web.Mvc;

public static class ActiveMenuHelper
{
    public static MvcHtmlString MenuLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, string areaName)
    {
        var currentAction = htmlHelper.ViewContext.RouteData.GetRequiredString("action");
        var currentController = htmlHelper.ViewContext.RouteData.GetRequiredString("controller");
        var currentArea = htmlHelper.ViewContext.RouteData.DataTokens["area"];

        var builder = new TagBuilder("li")
        {
            //InnerHtml = htmlHelper.ActionLink(linkText, actionName, controllerName).ToHtmlString()
            InnerHtml = "<a href=\"" + new UrlHelper(htmlHelper.ViewContext.RequestContext).Action(actionName, controllerName, new { area = areaName }).ToString() + "\">" + linkText + "</a>"
        };

        if (String.Equals(controllerName, currentController, StringComparison.CurrentCultureIgnoreCase) && String.Equals(actionName, currentAction, StringComparison.CurrentCultureIgnoreCase))
            builder.AddCssClass("active");

        return new MvcHtmlString(builder.ToString());
    }
}

and then in your partial view:然后在您的部分视图中:

@using YourProjectName.Helpers

<ul>
    @Html.MenuLink("Resume", "Index", "Resume", "" )
    @Html.MenuLink("Cover Letter", "Index", "CoverLetter", "" )
</ul>

You might not need the area , that is why you can leave it blank, i put it in here just in case.您可能不需要该区域,这就是您可以将其留空的原因,我把它放在这里以防万一。

Try adding this to your shared view .尝试将其添加到您的共享视图中。 normally "_Layout".通常是“_Layout”。

@{ 
    string pageUrl = Request.Url.PathAndQuery.ToString();
}

and instead of adding "active" class from the html markups, add conditional statement that will check the pageUrl just like the code below.并且不是从 html 标记中添加“活动”类,而是添加将检查 pageUrl 的条件语句,就像下面的代码一样。

@if (Request.IsAuthenticated)
{
    <ul style="list-style-type:none;">
        <li class="@(pageUrl.ToLower().Contains("/index/Resume") ? "active" : string.Empty) setBtnMargin">
            <a href="@Url.Action("Index", "Resume")" class="btn btn-block">My Resume </a>
        </li>
        <li class="@(pageUrl.ToLower().Contains("/index/CoverLetter") ? "active" : string.Empty) setBtnMargin">
            <a href="@Url.Action("Index", "CoverLetter")" class="btn btn-block">My Cover Letter </a>
        </li>
        <li class="@(pageUrl.ToLower().Contains("/index/Home") ? "active" : string.Empty) setBtnMargin">
            <a href="@Url.Action("Index", "Home")" class="btn btn-block">My Account </a>
        </li>
        <li class="@(pageUrl.ToLower().Contains("/index/Home") ? "active" : string.Empty) setBtnMargin">
            <a href="@Url.Action("Index", "Home")" class="btn  btn-block">Get Rewards </a>
        </li>
    </ul>
}

You have to add document ready function.您必须添加文档就绪功能。

<script>
$(document).ready(function(){
    $("ul").on("click", "li", function () {
        $('ul li').removeAttr('active');
        $(this).addClass('active');
    });
});
</script>

Try this sample one.试试这个示例。 it works for me.它对我有用。 :) :) :) :)

<script>
        $(document).ready(function(){
        $(window).load(function(){
            var x = window.location.href;
                $('ul a[href="'+x+'"]').each(function() {
                    if(x == window.location.href){
                        $('ul li').removeClass('active');
                        $(this).parent('li').addClass('active');
                    } 
                });
            });
        });
    </script>

I took a different approach, leveraging the fact that I use a load script for each partial view to load data into DataTables on that view.我采用了不同的方法,利用我为每个部分视图使用加载脚本将数据加载到该视图上的 DataTables 的事实。

I started by added an "id" to each of the menu items.我首先为每个菜单项添加了一个“id”。

<ul class="nav navbar-nav">
    <li id="Index"><a asp-page="/Index">Reportables</a></li>
    <li id="TaskAssayExclusion"><a asp-page="/TaskAssayExclusion">Task Assay Exclusions</a></li>
    <li id="SpecimenSite"><a asp-page="/SpecimenSite">Specimen Site</a></li>
    <li id="SnomedCT"><a asp-page="/SnomedCT">Snomed CT</a></li>
    <li id="Loinc"><a asp-page="/Loinc">LOINC</a></li>
    <li id="Search"><a asp-page="/Search">Search Messages</a></li>
</ul>

At the bottom of each partial view I have a snippet of JavaScript that gets executed when that view loads.在每个局部视图的底部,我都有一段 JavaScript,在该视图加载时执行。 An example of the snippet for the Index page is shown below.索引页面的代码片段示例如下所示。

<script type="text/javascript">
    function partialIndexModelScript() {
        $('li#Index').addClass('menu_item_active');
        filterLoadComplete = false;
        selectLoadComplete = false;
        loadReportableResultData();
    }
</script>

In my main JavaScript file, near the end of the $(document).ready() function I use 'typeof' to execute the relevant JavaScript snippet.在我的主要 JavaScript 文件中,靠近$(document).ready()函数的末尾,我使用“typeof”来执行相关的 JavaScript 代码段。

if (typeof partialIndexModelScript !== "undefined") partialIndexModelScript();
if (typeof partialSpecimenSiteModelScript !== "undefined") partialSpecimenSiteModelScript();
if (typeof partialNormalcyModelScript !== "undefined") partialNormalcyModelScript();
if (typeof partialSnomedCTModelScript !== "undefined") partialSnomedCTModelScript();
if (typeof partialLoincModelScript !== "undefined") partialLoincModelScript();
if (typeof partialTaskAssayExclusionModelScript !== "undefined") partialTaskAssayExclusionModelScript();
if (typeof partialSearchModelScript !== "undefined") partialSearchModelScript();

And finally the CSS which is nearly identical to the :hover CSS except that最后是几乎与 :hover CSS 相同的 CSS,除了
I've included the font-weight: bolder !important to really make the selected menu item stand out.我已经包括了font-weight: bolder !important真正让所选菜单项脱颖而出。

.menu_item_active {
    color: #B8B7DA !important;
    background-color: #514689 !important;
    text-decoration: underline !important;
    font-weight: bolder !important;
}

The final result:最终结果:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM