Twitter Bootstrap 标签页的活动类切换不起作用

23

我正在使用 Twitter Bootstrap 的导航选项卡和选项卡式菜单。这是我的 HTML 代码:

<div class="Header2" style="background-color:#1E3848">
    <div id="headerTab">
        <ul class="nav nav-tabs">
            <li class="active ans-tab"> <a href="http://myweb.com/">Home</a></li>
            <li class="topTab"><a href="http://myweb.com/score/">Score</a></li>
            <li class="topTab"><a href="http://myweb.com/leaderboards/">Leaderboards</a></li>
        </ul>
    </div>
    <div id="subHeaderTabPlayer">
        <ul class="nav nav-pills">
            <li class="active"> <a href="http://myweb.com/">Top</a></li>
            <li><a href="http://myweb.com/rules/" data-toggle="pill">Rules</a></li>
            <li><a href="http://myweb.com/player/" data-toggle="pill">Player</a></li>
            <li><a href="http://myweb.com/categories/" data-toggle="pill">Categories</a></li>
        </ul>
    </div>
</div>

如果我添加属性data-toggle="pill"data-toggle="tab",则具有活动类的选项卡会更改为我单击的选项卡。但是,href不再起作用。 如果我不使用这些类,href仍然有效,但是活动类不会更改,并且始终保持在页面加载时赋予该类的元素上。

我甚至尝试使用jQuery来切换类行为,但也无法正常工作。我的脚本代码如下:

<script type="text/javascript" src="//code.jquery.com/jquery-1.9.1.js"></script>
<script type="text/javascript">
    $(window).load(function(){
        document.getElementById( 'subHeaderTabPlayer' ).style.display = 'none';
        $('ul.nav-tabs li a').click(function (e) {
            var activeTab= document.getElementByClass('active');
            activeTab.removeAttribute("class");

            $('ul.nav-tabs li.active').removeClass('active')
            $(this).parent('li').addClass('active')
        })
        $('ul.nav-pills li a').click(function (e) {
            $('ul.nav-pills li.active').removeClass('active');
            $(this).parent('li').addClass('active');
        })
        $(".ans-tab").click(function() {
            document.getElementById('subHeaderTabPlayer').style.visibility = 'visible';
            document.getElementById('subHeaderTabPlayer' ).style.display = 'block';
        });
        $(".topTab").click(function() {
            document.getElementById('subHeaderTabPlayer').style.visibility = 'collapse';
            document.getElementById('subHeaderTabPlayer' ).style.display = 'none';
        });
    });
</script>

1
在我的情况下,问题是我在<ul class="nav nav-tabs">之后有一个div。因此,阅读您的帖子帮助我解决了这个问题。 - Peter
7个回答

29

Bootstrap的导航标签和胶囊需要使用JS插件。该插件在页面加载时被载入并负责突出显示当前活动的选项卡或胶囊,并记住其状态。如果链接指向其他页面,它会禁用href属性,因为当您单击链接到另一页时,将加载新页面。JS然后重新加载此新页面,它不知道当前活动的选项卡或胶囊。它们旨在与单页面应用程序或链接到同一页上的锚点一起使用,对于这个目的它们工作得很好。

jQuery的方法失败的原因相同,但可能更容易解释。

$('ul.nav-pills li a').click(function (e) {
  $('ul.nav-pills li.active').removeClass('active')
  $(this).parent('li').addClass('active')
})

当你点击链接时,JS会改变类(class),但前提是在下一页加载前有足够的时间执行。因为链接上的href属性告诉浏览器导航到新页面,所以新页面会被加载。新页面重新加载了你的JS,但它不可能记住来自之前页面的变量,比如哪个标签或者按钮应该是激活状态。

如果你将要导航到其他页面,最好直接在正在加载的特定页面上设置正确的选项卡(tab)的活动类(active class)。

如果你真的需要在客户端完成此操作,可以尝试以下方法,并在每个页面上加载它。

$(document).ready(function () {

  // Set BaseURL
  var baseURL = 'http://myweb.com/'

  // Get current URL and replace baseURL
  var href = window.location.href.replace(baseURL, '');

  // Remove trailing slash
  href = href.substr(-1) == '/' ? href.substr(0, href.length - 1) : href;

  // Get last part of current URL
  var page = href.substr(href.lastIndexOf('/') + 1);

  // Add trailing slash if not empty (empty means we're currently at baseURL)
  page = page != '' ? page + '/' : page;

  // Select link based on href attribute and set it's closest 'li' to 'active'. 
  // .siblings('.active').removeClass() is only needed if you have a default 'active li'.
  $('a[href="' + baseURL + page + '"]', '.nav li').closest('li').addClass('active').siblings('.active').removeClass();

});

根据URL的最后一部分设置活动选项卡,这在你的情况下(以及之前我的情况)有些具体。如果涉及文件扩展名或查询参数,你需要进行适当的调整。每个页面都至少需要在其中包含指向自身的链接。最好所有其他页面上呈现的标签和药片与其完全相同。

这些最后两点再次引发了我心中的想法:“如果您必须对正在呈现到页面上的内容具有如此多的控制,那么您可能可以访问服务器端”,如果是这种情况,您可以在那里进行修复,因为每个链接都会向服务器发送一个新的请求。此外,您的解决方案不必依赖于一些不太稳健的JavaScript才能工作。

所以这就是我曾经进行过的事情,你可以改进它,或者实现一种解决方案,在那里你可以将一些数据发布到下一个页面,并在JavaScript中读取它(如果需要处理文件扩展名或查询字符串,则这可能更容易和更可靠)。

祝你好运!:)


1
提示在最后一句。JS不是存储需要跨多个页面记住的内容的地方。您可以实现一种方法,在该方法中,您的JS接管导航而不是链接,然后向新页面发布某些值。但是,如果您要在实际页面之间导航,最好的方法是让一些服务器端逻辑在将页面发送到客户端之前决定哪个选项卡或pill将具有“active”类。或者,如果它们是静态页面,则为每个页面添加正确的标签或pill的活动类。 - Mathijs Flietstra
也许我可以在超链接中发送GET或POST请求。然后在我的页面上检查参数以激活类。对吧? - CodeMonkey
我可能会尝试通过更改与每个页面相关的模板文件中的类来解决此问题。谢谢。但我认为一定有其他方法。肯定已经有人遇到过这个问题了。 - CodeMonkey
事实上,我曾经自己遇到过这个问题,然后我自己构建了一个修复程序,然后意识到在服务器端修复它要容易得多。我会在答案中解释我是如何修复它的,因为你正在推动它 :) - Mathijs Flietstra
这种方法无法处理多个选项卡集合(例如单页面应用程序)。请参考我的答案,以获取另一种解决方案。 - kwcto
显示剩余3条评论

3

需要考虑的一点是:如果每个li元素使用不同的控制器,那么您可以尝试以下方法。

如何让Twitter-Bootstrap导航栏显示活动链接?

您的代码应该类似于:

<ul class="nav nav-pills">
  <li class="<%= 'active' if params[:controller] == 'home' %>"> <a href="link" data-toggle="pill">Top</a></li>
  <li class="<%= 'active' if params[:controller] == 'rules' %>"><a href="link" data-toggle="pill">Rules</a></li>
  <li class="<%= 'active' if params[:controller] == 'player' %>"><a href="link" data-toggle="pill">Player</a></li>
  <li class="<%= 'active' if params[:controller] == 'categories' %>"><a href="link" data-toggle="pill">Categories</a></li>
</ul>

1
这个例子对我有效:
$leftBlock.on("click", "#navFinished", function(){
  $('ul.nav-pills li.active').removeClass('active');
  $(this).addClass('active');
});

这个例子没有起作用。
$leftBlock.on("click", "#navFinished", function(){
  $('ul.nav-pills li.active').removeClass('active')
  $(this).parent('li').addClass('active')
})

移除 .parent("li") 有所帮助。

0
我按照@syeh的解决方案并成功了。以下是我的代码片段。
<ul class="nav nav-pills">
   <li <?php if (strchr($this->pageTitle,' Job') === ' Job') echo 'class=active';?>><?php echo CHtml::link('JOBS', array('Job/index'));?></li>
   <li <?php if (strchr($this->pageTitle,'Artisan') === 'Artisan') echo 'class=active';?>><?php echo CHtml::link('ARTISANS', array('Artisan/index'));?></li>
   <li <?php if (strchr($this->pageTitle,'Task') === 'Task') echo 'class=active';?>><?php echo CHtml::link('TASKS',array('Task/index'));?></li>
</ul>

0
以下是一个更通用的客户端解决方案,使用jQuery实现。它假定你的选项卡具有data-toggle属性,并且每组选项卡都包含在某种容器元素中。
$('[data-toggle="tab"],[data-toggle="pill"]').click(function() { 
    $(this).parent().children('.active[data-toggle="tab"],.active[data-toggle="pill"]').removeClass('active'); 
    $(this).addClass('active'); 
});

0

我遇到了类似的问题:当点击选项卡时,它们会变为活动状态,但无法正确地从其他选项卡中删除active类(即用户在页面视图上单击的每个选项卡都将具有active类)。

<ol>切换为<ul>可以使选项卡正常工作。


-1
<?php
function activate($uri) {
    if ($_SERVER['REQUEST_URI'] == $uri) {
        echo ' class="active" ';
    }
}

?>

<nav>
    <ul class="nav nav-tabs">
      <li role="tab" <?php activate('/wikireport/index.php'); ?> ><a href="index.php" aria-controls="Home">Wiki Report</a></li>
      <li role="tab" <?php activate('/wikireport/examples.php'); ?> ><a href="examples.php" aria-controls="Examples">Examples</a></li>
      <li role="tab" <?php activate('/wikireport/about.php'); ?> ><a href="about.php" aria-controls="About">About</a></li>
    </ul>
</nav>

然后在“content”文件中,只需require/include您的navline.php

<?php 
include('navline.php'); 
?>

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