Twitter Bootstrap标签页:在页面重新加载或超链接时跳转到特定的标签页

386

我正在开发一个网页,使用Twitter的Bootstrap框架和他们的Bootstrap Tabs JS。它非常好用,除了一些小问题之外,其中之一是我不知道如何从外部链接直接跳转到特定选项卡。例如:

<a href="facility.php#home">Home</a>
<a href="facility.php#notes">Notes</a>

当从外部页面点击链接时,应分别跳转到主页和笔记选项卡


61
希望这个能内置! - Damon
6
这个问题也在这里被提出过:https://github.com/twitter/bootstrap/issues/2415 (并且那里有几个解决方案)。 - Ztyx
1
更新的 Bootstrap 问题链接为 https://github.com/twbs/bootstrap/issues/2415。 - bmihelac
这是一个更完整的解决方案,对我很有帮助:https://dev59.com/W2ct5IYBdhLWcg3wZMfn#22160443 - Ruben
3
可解决此问题的插件为:https://github.com/timabell/jquery.stickytabs/ - Tim Abell
显示剩余3条评论
26个回答

675

以下是我的解决方案,可能有点晚了,但它可能对其他人有所帮助:

// Javascript to enable link to tab
var hash = location.hash.replace(/^#/, '');  // ^ means starting, meaning only match the first hash
if (hash) {
    $('.nav-tabs a[href="#' + hash + '"]').tab('show');
} 

// Change hash for page-reload
$('.nav-tabs a').on('shown.bs.tab', function (e) {
    window.location.hash = e.target.hash;
})

97
我会再添加一行额外的代码 window.scrollTo(0, 0);,以确保窗口始终滚动到顶部。 - Trung Lê
1
适用于我个人的在线代码:window.location.hash && $('li a[href="' + window.location.hash+ '"]').tab('show').trigger("click"); - Dean Meehan
10
这是Bootstrap 3的演示:http://www.bootply.com/render/VQqzOawoYc#tab2,以及[源代码](http://www.bootply.com/VQqzOawoYc)。 - Carol Skelly
1
以这种方式访问哈希会导致安全漏洞。如果恶意用户将JavaScript注入哈希字符串中,并且您在此处未对其进行净化,则将允许他们执行任意代码。请注意,在使用哈希信息之前,请务必剥离它! - jaypb
2
将jquery从1.09升级到1.11后,我收到了这个错误:语法错误,无法识别的表达式:.nav-tabs a[href=#tab-2]。使用https://dev59.com/W2ct5IYBdhLWcg3wZMfn 已解决。 - Pietro Z.
显示剩余17条评论

216

更新

对于 Bootstrap 3,将 .on('shown', ...) 改为 .on('shown.bs.tab', ....)


这是基于 @dubbe 的回答和这个被接受的 SO 回答。它解决了 window.scrollTo(0,0) 不正确工作的问题。问题在于当你替换标签时,浏览器会滚动到该标签,因为它是页面上的一个元素。为了解决这个问题,加一个前缀,这样哈希不引用实际的页面元素。

// Javascript to enable link to tab
var hash = document.location.hash;
var prefix = "tab_";
if (hash) {
    $('.nav-tabs a[href="'+hash.replace(prefix,"")+'"]').tab('show');
} 

// Change hash for page-reload
$('.nav-tabs a').on('shown', function (e) {
    window.location.hash = e.target.hash.replace("#", "#" + prefix);
});

使用示例

如果您有一个id为"mytab"的tab-pane,您需要这样放置链接:

<a href="yoursite.com/#tab_mytab">Go to Specific Tab </a>

1
有没有一种简单的方法可以引用位于特定选项卡下的书签?我的页面上有五个选项卡,在这些选项卡下面我有许多书签。我想要的是使这些书签可以从选项卡外部链接。 - nize
如果您创建一个 jsfiddle 并展示您正在尝试做的事情,我会尝试查看一下。 - flynfish
1
这是一个针对Bootstrap 3的Bootlpy演示:http://www.bootply.com/render/VQqzOawoYc#tab2,以及[源代码](http://www.bootply.com/VQqzOawoYc)。 - Carol Skelly
上面的示例缺少 href 上的双引号。第 5 行应该是:$('.nav-tabs a[href="'+hash.replace(prefix,"")+'"]').tab('show'); - Ponyboy
对我来说可以工作,除了我不得不删除“yoursite.com/anotherpage/#tab_mytab”中的最后一个正斜杠(在#之前),否则它会对页面加载造成严重影响。 - user6743474
只是为了解释“像这样放置您的链接”部分:这是指您想要链接到带有标签的页面上的另一页上的链接。它不是指nav-tabs链接。那些链接仍然具有相同的哈希值。 - timetofly

59

您可以触发相应选项卡链接的click事件:

$(document).ready(function(){

  if(window.location.hash != "") {
      $('a[href="' + window.location.hash + '"]').click()
  }

});

谢谢你的提示!这个方法很好用,只有一个小问题。刷新页面时,无法跳转到正确的选项卡。按Ctrl+F5可以解决。我修改了代码如下:$(document).ready(function(){ function getUrlVars() { var vars = {}; var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) { vars[key] = value; }); return vars; } var action = getUrlVars()["action"]; if (action != "") { $('a[href="#' + action + '"]').click() }; }); - mraliks

47

这是dubbe解决方案的改进实现,可以防止滚动。

// Javascript to enable link to tab
var url = document.location.toString();
if (url.match('#')) {
    $('.nav-tabs a[href="#'+url.split('#')[1]+'"]').tab('show') ;
} 

// With HTML5 history API, we can easily prevent scrolling!
$('.nav-tabs a').on('shown.bs.tab', function (e) {
    if(history.pushState) {
        history.pushState(null, null, e.target.hash); 
    } else {
        window.location.hash = e.target.hash; //Polyfill for old browsers
    }
})

24

尽管提供的JavaScript解决方案可能有效,但我选择了稍微不同的方法,它不需要额外的JavaScript,但需要在视图中使用逻辑。您可以创建一个带有标准URL参数的链接,例如:

<a href = "http://link.to.yourpage?activeTab=home">My Link</a>

然后,您只需检测activeTab的值,并在适当的

  • 中写入'class="active"'。

    伪代码(根据您的编程语言实现)。请注意,在此示例中,如果未提供参数,则将“主页”选项卡设置为默认活动选项卡。

    $activetabhome = (params.activeTab is null or params.activeTab == 'home') ? 'class="active"' : '';
    $activetabprofile = (params.activeTab == 'profile') ? 'class="active"' : '';
    
    <li $activetabhome><a href="#home">Home</a></li>
    <li $activetabprofile><a href="#profile">Profile</a></li>
    

  • 1
    我更喜欢你的解决方案而不是JS解决方案,因为一个简单的原因是JS location.hash会跳转到ID,导致光标位置上下跳动。 - Trung Lê
    1
    我更喜欢这个解决方案。事实上,我为选项卡创建了新的路由,并通过相应地设置活动类别重新生成了视图。这避免了页面调整大小、URL哈希和页面滚动等问题。 - Vijay Meena
    更好的解决方案。 - HappyCoder

    11

    我不是if...else的忠实拥护者,所以我采用了更简单的方法。

    $(document).ready(function(event) {
        $('ul.nav.nav-tabs a:first').tab('show'); // Select first tab
        $('ul.nav.nav-tabs a[href="'+ window.location.hash+ '"]').tab('show'); // Select tab by name if provided in location hash
        $('ul.nav.nav-tabs a[data-toggle="tab"]').on('shown', function (event) {    // Update the location hash to current tab
            window.location.hash= event.target.hash;
        })
    });
    
    1. 选择默认标签(通常是第一个)
    2. 切换标签(如果确实存在这样的元素;让jQuery处理它);如果指定了错误的哈希,则不会发生任何事情
    3. [可选] 如果手动选择了另一个标签,则更新哈希

    这并没有解决滚动到请求的哈希值的问题; 但是应该吗?


    10

    8
    这适用于Bootstrap 3,并通过整合GarciaWebDev的答案(允许在哈希后使用url参数,直接来自Bootstrap作者在github问题跟踪器上)改进了dubbe和flynfish的2个顶级答案:
    // Javascript to enable link to tab
    var hash = document.location.hash;
    var prefix = "tab_";
    
    if (hash) {
        hash = hash.replace(prefix,'');
        var hashPieces = hash.split('?');
        activeTab = $('.nav-tabs a[href=' + hashPieces[0] + ']');
        activeTab && activeTab.tab('show');
    } 
    
    // Change hash for page-reload
    $('.nav-tabs a').on('shown', function (e) {
        window.location.hash = e.target.hash.replace("#", "#" + prefix);
    });
    

    1
    这在Bootstrap 3中不起作用,根据文档,'shown'应该是'shown.bs.tab':http://getbootstrap.com/javascript/#tabs-events。我很困惑,但当我尝试编辑您的帖子时,它被拒绝了... - YPCrumble

    8
    建立在Demircan Celebi的解决方案基础上;我想要当修改URL时标签页可以打开,而不需要重新从服务器加载页面。
    <script type="text/javascript">
        $(function() {
            openTabHash(); // for the initial page load
            window.addEventListener("hashchange", openTabHash, false); // for later changes to url
        });
    
    
        function openTabHash()
        {
            console.log('openTabHash');
            // Javascript to enable link to tab
            var url = document.location.toString();
            if (url.match('#')) {
                $('.nav-tabs a[href="#'+url.split('#')[1]+'"]').tab('show') ;
            } 
    
            // With HTML5 history API, we can easily prevent scrolling!
            $('.nav-tabs a').on('shown.bs.tab', function (e) {
                if(history.pushState) {
                    history.pushState(null, null, e.target.hash); 
                } else {
                    window.location.hash = e.target.hash; //Polyfill for old browsers
                }
            })
        }
    </script>
    

    7

    只需将此代码插入您的页面:

    $(function(){
      var hash = window.location.hash;
      hash && $('ul.nav a[href="' + hash + '"]').tab('show');
    
      $('.nav-tabs a').click(function (e) {
        $(this).tab('show');
        var scrollmem = $('body').scrollTop();
        window.location.hash = this.hash;
        $('html,body').scrollTop(scrollmem);
      });
    });


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