Bootstrap 导航栏的活动状态无法正常显示

101

我使用的是bootstrap v3。

我在我的navbar上使用了class="active",但当我点击菜单项时它没有切换。我知道如何使用jQuery并构建一个click函数来实现这一点,但我认为这个功能应该包括在bootstrap中?所以也许这是一个JavaScript问题?

这是我的头部文件,包含了我的js/css/bootstrap文件:

<!-- Bootstrap CSS -->
<link rel="stylesheet" href= "/bootstrap/css/bootstrap.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" />
<link rel="stylesheet" href= "/stylesheets/styles.css" />

<!--jQuery -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>

<!-- Bootstrap JS -->
<script src="/bootstrap/js/bootstrap.min.js"></script>
<script src="/bootstrap/js/bootstrap-collapse.js"></script>
<script src="/bootstrap/js/bootstrap-transition.js"></script>

这是我的导航栏代码:

<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
        <div class="container-fluid">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbarCollapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>

                <a class="navbar-brand" href="/index.php">MyBrand</a>
            </div>

            <div class="collapse navbar-collapse navbarCollapse">
                <ul class="nav navbar-nav navbar-right">
                    <li class="active">
                        <a href="/index.php">Home</a>
                    </li>

                    <li>
                        <a href="/index2.php"> Links</a>
                    </li>

                    <li>
                        <a href="/history.php">About</a>
                    </li>
                    <li>
                        <a href="/contact.php">Contact</a>
                    </li>

                    <li>
                        <a href="/login.php">Login</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>

我设置得对吗?

(另外一个问题,可能与此相关吗?当菜单变成移动端时,我点击菜单按钮它会折叠起来。但再次点击它无法展开。这个问题和其他问题一起,是否意味着JavaScript设置错误?)


3
自从我开始使用Bootstrap,我认为Bootstrap并没有自动处理这个问题,你需要手动设置active class...如果我错了,那我会从中学到很多东西... - BENARD Patrick
1
嗯,@TheLittlePig是正确的,当您的应用程序生成HTML时,您需要自己添加“active”类。 - DavidG
32个回答

157

您已经包含了被minify过的Bootstrap js文件以及折叠/过渡插件,但文档指出:

bootstrap.js和bootstrap.min.js都包含所有插件在一个文件中。
只需要包含其中一个。

并且

对于简单的转场效果,请同时包括transition.js和其他JS文件。 如果您正在使用编译(或minify)的bootstrap.js,则无需包含它—它已经存在。

所以这可能是您最小化问题的原因。

对于active类,您必须自己进行管理,但只需要一两行代码即可。

Bootstrap 3:

$(".nav a").on("click", function(){
   $(".nav").find(".active").removeClass("active");
   $(this).parent().addClass("active");
});

Bootply:http://www.bootply.com/IsRfOyf0f9

Bootstrap 4:

$(".nav .nav-link").on("click", function(){
   $(".nav").find(".active").removeClass("active");
   $(this).addClass("active");
});

2
如果您从href移动到另一个页面(不是哈希而是发送另一个请求),这是否有效? - Blaszard
1
在非单页应用/网站中,你应该默认将active类添加到nav项目上。 - Pete TNT
7
对我来说它不起作用,它会被添加但在下一秒钟它会回到初始的活动类别,所以它不能保留在页面上,请有人帮忙解决一下。 - sourav78611
15
@Pete TNT - 还不够清楚,当人们给出90%的解决方案并假设每个人都知道如何应用剩下的10%时,这非常令人沮丧。特别是在语法难以正确使用的情况下。 - Dave
3
由于您在点击链接时刷新了页面,因此出现了这种情况。这个解决方案适用于Ajax请求。对于非Ajax请求,请参考Jon提供的解决方案。 - A P
显示剩余11条评论

112

这是我用于切换活动页面的解决方案

$(document).ready(function() {
  $('li.active').removeClass('active').removeAttr('aria-current');
  $('a[href="' + location.pathname + '"]').closest('li').addClass('active').attr('aria-current', 'page'); 
});

2
我们应该把这个放在哪里?抱歉,我是JS新手 :# - mrateb
3
这个在 Bootstrap 4 中运行得很好。@Thomas8:这应该放在 <script></script> 标签之间,位于 HTML 文件底部的 </body> 标签之前(假设您的所有内容都在一个 HTML 文件中)。 - alwaysCurious
1
我正在使用Bootstrap 4,这对我很有效。谢谢。 - Qwerty
1
非常好!如果菜单url包含搜索参数,请使用“location.pathname + location.search”替换“location.pathname”,以使其正常工作! - xjlin0
1
如果菜单项是页面导航,您还应该设置aria-current="page"来为辅助技术标记活动菜单项。也许可以简单地使用.removeClass('active').removeAttr('aria-current');.addClass('active').attr('aria-current', 'page'); - Andy
显示剩余6条评论

20

这对我非常有效,因为“window.location.pathname”中也包含真正页面名称之前的数据,例如目录/页面.php。因此,只有当URL包含此链接时,实际导航栏链接才会设置为活动状态。

$(document).ready(function() {
    $.each($('#navbar').find('li'), function() {
        $(this).toggleClass('active', 
            window.location.pathname.indexOf($(this).find('a').attr('href')) > -1);
    }); 
});

6
除了你的解决方案,其他所有的解决方案都不起作用,我一个一个地尝试过了。 - Lynob

14

使用Bootstrap 3.3.4版本,在较长的HTML页面上,您可以通过类或ID引用页面的部分,使用spy-scroll与body元素一起管理活动的导航栏链接:

  <body data-spy="scroll" data-target="spy-scroll-id">

数据目标将是一个id为"spy-scroll-id"的div

    <div id="spy-scroll-id" class="collapse navbar-collapse">
      <ul class="nav navbar-nav">
        <li class="active"><a href="#topContainer">Home</a></li>
        <li><a href="#details">About</a></li>
        <li><a href="#carousel-container">SlideShow</a></li>
      </ul>
    </div>

这应该可以通过点击来激活链接,无需任何javascript函数,并且还将在您滚动到相应链接部分时自动激活每个链接,而js onclick()不会实现此功能。


1
谢谢。应该是:data-target="#spy-scroll-id",而不是 data-target="spy-scroll-id"。 - Vdex

11
你所需要做的就是在Bootstrap导航栏中的链接上添加data-toggle="tab",像这样简单地完成:

<ul class="nav navbar-nav">
  <li class="active"><a data-toggle="tab" href="#">Home</a></li>
  <li><a data-toggle="tab" href="#">Test</a></li>
  <li><a data-toggle="tab" href="#">Test2</a></li>
</ul>

这真的很有用,但是当您拥有一个navbar-nav(正常)和一个navbar-right第二个列表时,它无法正常工作。最终会出现两个未被清除的活动状态。 - Karl P
5
当我添加了"data-toggle"时,页面无法跳转到href中指定的"#place"。 - scorpiozj
实际上这是一个更新。正如@scorpiozj所提到的。当这个被添加时,链接本身无法工作。 - mrateb

9
如果您不使用锚链接,可以使用类似于以下内容的方式:
$(document).ready(function () {
    $.each($('#navbar').find('li'), function() {
        $(this).toggleClass('active',
            '/' + $(this).find('a').attr('href') == window.location.pathname);
    });
});

6

使用Bootstrap 4,您可以这样使用:

$(document).ready(function() {
    $(document).on('click', '.nav-item a', function (e) {
        $(this).parent().addClass('active').siblings().removeClass('active');
    });
});

谢谢,不知道为什么其他的(Bootstrap 3)没起作用。 - information_interchange

5

这个优雅的解决方案对我很有帮助。欢迎提出新的想法/建议。

$( document ).on( 'click', '.nav-list li', function ( e ) {
    $( this ).addClass( 'active' ).siblings().removeClass( 'active' );
} );

您可以使用jQuery的“siblings()”方法,仅保持所访问的项目处于活动状态,其兄弟项目处于非活动状态。

这里的 .nav-list 是什么? - Parteek Kumar Kherpa

5

我使用这个。它简短、优雅且易于理解。

$(document).ready(function() {
    $('a[href$="' + location.pathname + '"]').addClass('active');
});

3

Bootstrap 5的原生JS解决方案

document.addEventListener("DOMContentLoaded", function () {
    // make all currently active items inactive
    // (you can delete this block if you know that there are no active items when loading the page)
    document.querySelectorAll("a.nav-link.active").forEach(li => {
        li.classList.remove("active");
        li.attributes.removeNamedItem("aria-current");
    });

    // find the link to the current page and make it active
    document.querySelectorAll(`a[href="${location.pathname}"].nav-link`).forEach(a => {
        a.classList.add("active");
        a.setAttribute("aria-current", "page");
    });
});

对我有效的唯一解决方案。我正在使用bootstrap 5-1.0.11。 - prsnr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接