最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Navbar active class resets on page load - Stack Overflow

programmeradmin2浏览0评论

Using bootstrap 4 and asp core for a personal project I've been tinkering with for the past couple of months. I've got a navbar in my _Layout that is shared across my entire site. I've also got some css that styles the navbar link text.

I'm trying to change the active class on the links so the currently-visited controller is highlighted with a different color. I'm using js to do this. The color is changing initially, so I'm sure that the js is adding the active class to the new link and removing it from the previous active link, but when the page finishes loading, they reset and the active class goes back to Home.

Here is my navbar in _Layout.cshtml:

<nav class="navbar navbar-toggleable-md navbar-inverse bg-inverse">
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarToggler" aria-controls="navbarToggler" aria-expanded="false" aria-label="Toggle navigation">
    <img src="~/images/logo1.png" width="40" height="40" alt="" />
</button>
<div class="collapse navbar-collapse" id="navbarToggler">
    <ul class="nav navbar-nav mr-auto mt-2 mt-lg-0">
        <li class="nav-item active">
            <a class="nav-link" asp-action="Index" asp-controller="Home">Home<span class="sr-only">(current)</span></a>
        </li>
        <li class="nav-item">
            <a class="nav-link" asp-action="Index" asp-controller="aaaa">Aaaa</a>
        </li>
        <li class="nav-item">
            <a class="nav-link" asp-action="Index" asp-controller="bbbb">Bbbb</a>
        </li>
        <li class="nav-item">
            <a class="nav-link" asp-action="Index" asp-controller="cccc">Cccc</a>
        </li>
        <li class="nav-item">
            <a class="nav-link" asp-action="Index" asp-controller="dddd">Dddd</a>
        </li>
    </ul>
    <form class="form-inline my-2 my-lg-0">
        <button class="btn btn-outline-danger btn-sm"
                type="submit" asp-action="Login" asp-controller="Account">
            Login
        </button>
    </form>
</div>

Here is the js that I'm declaring in the @scripts section of _Layout:

$( '.navbar-inverse .navbar-nav a' ).on( 'click', function () {
    $( '.navbar-inverse .navbar-nav' ).find( 'li.active' ).removeClass( 'active' );
    $( this ).parent( 'li' ).addClass( 'active' );
});

And my css:

.navbar-inverse .navbar-nav .open > .nav-link, 
.navbar-inverse .navbar-nav .active > .nav-link, 
.navbar-inverse .navbar-nav .nav-link.open, 
.navbar-inverse .navbar-nav .nav-link.active {
    color: yellow;
}

Why is the active link being reset when the new page loads? I know the js is working because while the page is loading, "Home" is not yellow anymore, but the new link I clicked in the navbar is yellow. But when the loading is plete, the yellow goes back to Home. Any insights would be appreciated, I'm rather new at software development.

Using bootstrap 4 and asp core for a personal project I've been tinkering with for the past couple of months. I've got a navbar in my _Layout that is shared across my entire site. I've also got some css that styles the navbar link text.

I'm trying to change the active class on the links so the currently-visited controller is highlighted with a different color. I'm using js to do this. The color is changing initially, so I'm sure that the js is adding the active class to the new link and removing it from the previous active link, but when the page finishes loading, they reset and the active class goes back to Home.

Here is my navbar in _Layout.cshtml:

<nav class="navbar navbar-toggleable-md navbar-inverse bg-inverse">
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarToggler" aria-controls="navbarToggler" aria-expanded="false" aria-label="Toggle navigation">
    <img src="~/images/logo1.png" width="40" height="40" alt="" />
</button>
<div class="collapse navbar-collapse" id="navbarToggler">
    <ul class="nav navbar-nav mr-auto mt-2 mt-lg-0">
        <li class="nav-item active">
            <a class="nav-link" asp-action="Index" asp-controller="Home">Home<span class="sr-only">(current)</span></a>
        </li>
        <li class="nav-item">
            <a class="nav-link" asp-action="Index" asp-controller="aaaa">Aaaa</a>
        </li>
        <li class="nav-item">
            <a class="nav-link" asp-action="Index" asp-controller="bbbb">Bbbb</a>
        </li>
        <li class="nav-item">
            <a class="nav-link" asp-action="Index" asp-controller="cccc">Cccc</a>
        </li>
        <li class="nav-item">
            <a class="nav-link" asp-action="Index" asp-controller="dddd">Dddd</a>
        </li>
    </ul>
    <form class="form-inline my-2 my-lg-0">
        <button class="btn btn-outline-danger btn-sm"
                type="submit" asp-action="Login" asp-controller="Account">
            Login
        </button>
    </form>
</div>

Here is the js that I'm declaring in the @scripts section of _Layout:

$( '.navbar-inverse .navbar-nav a' ).on( 'click', function () {
    $( '.navbar-inverse .navbar-nav' ).find( 'li.active' ).removeClass( 'active' );
    $( this ).parent( 'li' ).addClass( 'active' );
});

And my css:

.navbar-inverse .navbar-nav .open > .nav-link, 
.navbar-inverse .navbar-nav .active > .nav-link, 
.navbar-inverse .navbar-nav .nav-link.open, 
.navbar-inverse .navbar-nav .nav-link.active {
    color: yellow;
}

Why is the active link being reset when the new page loads? I know the js is working because while the page is loading, "Home" is not yellow anymore, but the new link I clicked in the navbar is yellow. But when the loading is plete, the yellow goes back to Home. Any insights would be appreciated, I'm rather new at software development.

Share Improve this question edited Jan 31, 2018 at 15:15 cjens19 asked Jan 31, 2018 at 14:53 cjens19cjens19 933 silver badges7 bronze badges 0
Add a ment  | 

2 Answers 2

Reset to default 7

You're setting active on click. However, when the browser actually goes to that URL following the click, a pletely different view is rendered. Therefore, there's no concept of anything having been set a certain way or done previously.

Instead, you need to either have your JS run onload, or simply just send the HTML with the correct item active in the first place, and throw away the JS. The easiest way to do that is something like:

@{ string url; }

Then for each nav link:

@{ url = Url.Action("Foo", "Bar"); }
<li class="@(Request.Path.StartsWith(url) ? "active" : null)">
    <a href="@url">Foo</a>
</li>

Setting the url variable is mostly just a way to not repeat yourself with the action/controller for the link, since you need the link URL in two different places.

The meat is in the ternary. If the current URL path starts with this link's URL (which should cover both the scenario of being equal to and just being a parent of the current URL), then you apply the active class.

EDIT

Because of using StartsWith, a link for "Home" will basically always be set as active, since every URL would start with /. You probably want to make an exception on that link and instead just do:

@{ url = Url.Action("Index", "Home"); }
<li class="@(Request.Path == url ? "active" : null)">
    <a href="@url">Home</a>
</li>

Then, that link will only be marked active if the URL is actually /.

Thanks to @Chris Pratt for his guidance. I got this working albeit with a couple of changes, possibly due to me changing my mind on the navbar and moving to a tabbed navbar (like Twitter's mobile app uses). Here's my navbar code in _Layout.cshtml:

<!--navbar-->
@{ string url; }

<ul class="nav navbar-dark bg-dark nav-tabs nav-fill">
    @{ url = Url.Action("Index", "Home"); }
    <li class="nav-item">
        <a class="nav-link @(Context.Request.Path == url ? "active" : null)" href="@url">Home</a>
    </li>
    @{ url = Url.Action("Index", "Spells"); }
    <li class="nav-item">        
        <a class="nav-link @(Context.Request.Path.StartsWithSegments(url) ? "active" : null)" href="@url">Spells</a>
    </li>
    @{ url = Url.Action("Index", "Crits"); }
    <li class="nav-item">        
        <a class="nav-link @(Context.Request.Path.StartsWithSegments(url) ? "active" : null)" href="@url">Crits</a>
    </li>
    @{ url = Url.Action("Index", "Journal"); }
    <li class="nav-item">        
        <a class="nav-link @(Context.Request.Path.StartsWithSegments(url) ? "active" : null)" href="@url">Journal</a>
    </li>
</ul>

Now that the active class switching is working as expected, I can add some styling, and replace the text with icons that I'll make.

Gave you an upvote, Chris Pratt, but my rep is too low to show it publicly for now. Thanks again.

发布评论

评论列表(0)

  1. 暂无评论