【问题标题】:Twitter Bootstrap Tabs: Go to Specific Tab on Page Reload or HyperlinkTwitter Bootstrap 选项卡:在页面重新加载或超链接时转到特定选项卡
【发布时间】:2011-12-13 07:36:36
【问题描述】:

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

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

当点击来自外部页面的链接时,应该分别转到主页选项卡和备注选项卡

【问题讨论】:

标签: javascript html tabs twitter-bootstrap


【解决方案1】:

这是我对问题的解决方案,可能有点晚了。但它也许可以帮助其他人:

// 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;
})

【讨论】:

  • 我会多加 1 行 window.scrollTo(0, 0); 以确保窗口始终滚动到顶部
  • $('.nav-tabs a[href*=#'+url.split('#')[1]+']').tab('show') ; // 带 * 更安全,否则它只匹配第一个 #...
  • 对我有用的在线:window.location.hash && $('li a[href="' + window.location.hash+ '"]').tab('show').trigger (“点击”);
  • 这是 Bootstrap 3 的演示:bootply.com/render/VQqzOawoYc#tab2source code
  • 将 jquery 从 1.09 升级到 1.11 后,我收到此错误:Syntax error, unrecognized expression: .nav-tabs a[href=#tab-2]。使用stackoverflow.com/questions/12131273/… 解决
【解决方案2】:

更新

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


这是基于@dubbe 答案和SO accepted answer。它处理window.scrollTo(0,0) 无法正常工作的问题。问题是,当您替换显示的选项卡上的 url 哈希时,浏览器将滚动到该哈希,因为它是页面上的一个元素。为了解决这个问题,添加一个前缀,这样哈希就不会引用实际的页面元素

// 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" 的选项卡窗格,您需要这样放置链接:

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

【讨论】:

  • 是否有一种简单的方法来引用位于特定选项卡下的书签?我的页面上有五个标签,在这些标签下我有许多书签。我想要的是使这些书签可以从标签外部链接。
  • @nize 如果你用你想要做的事情创建一个 jsfiddle,我会试着看看。
  • 这是 Bootstrap 3 的 Bootlpy 演示:bootply.com/render/VQqzOawoYc#tab2source code
  • 上面的例子缺少href上的双引号。第 5 行应该是:$('.nav-tabs a[href="'+hash.replace(prefix,"")+'"]').tab('show');
  • 对我有用,但我必须删除 'yoursite.com/anotherpage/#tab_mytab' 中的最后一个正斜杠(在 # 之前),否则它会对页面加载造成严重破坏。
【解决方案3】:

您可以在相应的选项卡链接上触发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() }; }); `
【解决方案4】:

这是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
    }
})

【讨论】:

    【解决方案5】:

    虽然提供的 JavaScript 解决方案可能有效,但我采用了一种稍微不同的方式,不需要额外的 JavaScript,但在您看来确实需要逻辑。您使用标准 URL 参数创建链接,例如:

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

    然后你只需检测activeTab的值在适当的&lt;li&gt;中写入'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>
    

    【讨论】:

    • 我更喜欢你的解决方案而不是 JS 解决方案,因为一个简单的原因是 JS location.hash 会跳转到导致光标位置上下移动的 ID。
    • 我更喜欢这个解决方案。事实上,我通过相应地设置活动类为选项卡创建了新路由并重新生成了视图。这避免了页面调整大小、url 哈希和页面滚动带来的麻烦。
    【解决方案6】:

    我不是 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. 切换到选项卡(如果确实存在这样的元素;让 j​​Query 处理它);如果指定了错误的哈希,则不会发生任何事情
    3. [可选] 如果手动选择另一个选项卡,则更新哈希

    不解决滚动到请求的哈希;但是应该吗?

    【讨论】:

      【解决方案7】:

      对于引导程序 3:

      $('.nav-tabs a[href="#' + tabID + '"]').tab('show');
      

      https://jsfiddle.net/DTcHh/6638/

      【讨论】:

        【解决方案8】:

        这在 Bootstrap 3 中有效,并通过集成 GarciaWebDev 的答案来改进 dubbe 和 flynfish 的 2 个最佳答案(它允许在哈希之后使用 url 参数,并且直接来自 github 问题跟踪器上的 Bootstrap 作者):

        // 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);
        });
        

        【讨论】:

        • 这在 Bootstrap 3 中不起作用,'shown' 应该是 'shown.bs.tab' 每个文档:getbootstrap.com/javascript/#tabs-events。我很困惑为什么但是当我试图编辑你的帖子时它被拒绝了......
        【解决方案9】:

        以 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>
        

        【讨论】:

          【解决方案10】:

          此代码根据#hash 选择正确的选项卡,并在单击选项卡时添加正确的#hash。 (这里使用 jquery)

          在咖啡脚本中:

          $(document).ready ->
              if location.hash != ''
                  $('a[href="'+location.hash+'"]').tab('show')
          
              $('a[data-toggle="tab"]').on 'shown', (e) ->
                  location.hash = $(e.target).attr('href').substr(1)
          

          或在 JS 中:

          $(document).ready(function() {
              if (location.hash !== '') $('a[href="' + location.hash + '"]').tab('show');
              return $('a[data-toggle="tab"]').on('shown', function(e) {
                return location.hash = $(e.target).attr('href').substr(1);
              });
          });
          

          【讨论】:

          • 确保在 jquery 加载后放置这个。我把它放在页面中间(这是一个很容易插入它进行测试的地方)但它不起作用。在我加载 jquery 之后放置它效果很好。
          【解决方案11】:
          $(function(){
            var hash = window.location.hash;
            hash && $('ul.nav a[href="' + hash + '"]').tab('show');
          });
          

          http://github.com/twitter/bootstrap/issues/2415#issuecomment-4450768 的这段代码非常适合我。

          【讨论】:

            【解决方案12】:

            我用于嵌套标签的@flynfish + @Ztyx 解决方案:

                handleTabLinks();
            
                function handleTabLinks() {
                    if(window.location.hash == '') {
                        window.location.hash = window.location.hash + '#_';
                    }
                    var hash = window.location.hash.split('#')[1];
                    var prefix = '_';
                    var hpieces = hash.split('/');
                    for (var i=0;i<hpieces.length;i++) {
                        var domelid = hpieces[i].replace(prefix,'');
                        var domitem = $('a[href=#' + domelid + '][data-toggle=tab]');
                        if (domitem.length > 0) {
                            domitem.tab('show');
                        }
                    }
                    $('a[data-toggle=tab]').on('shown', function (e) {
                        if ($(this).hasClass('nested')) {
                            var nested = window.location.hash.split('/');
                            window.location.hash = nested[0] + '/' + e.target.hash.split('#')[1];
                        } else {
                            window.location.hash = e.target.hash.replace('#', '#' + prefix);
                        }
                    });
                }
            

            孩子应该有 class="nested"

            【讨论】:

            • 你能解释一下当你有 / 在哈希吗?
            【解决方案13】:

            我想出了一个使用 url 哈希或 localStorage 的解决方案,具体取决于后者的可用性,代码如下:

            $(function(){
                $(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
                    localStorage.setItem('activeTab', $(e.target).attr('href'));
                })
            
                var hash = window.location.hash;
                var activeTab = localStorage.getItem('activeTab');
            
                if(hash){
                      $('#project-tabs  a[href="' + hash + '"]').tab('show');   
                }else if (activeTab){
                    $('#project-tabs a[href="' + activeTab + '"]').tab('show');
                }
            });
            

            【讨论】:

              【解决方案14】:

              我建议您使用 Bootstrap 作者在其issue tracker on GitHub 上提供的代码:

              var hash = location.hash
                , hashPieces = hash.split('?')
                , activeTab = $('[href=' + hashPieces[0] + ']');
              activeTab && activeTab.tab('show');
              

              您可以在该问题的链接上找到有关他们为何不选择支持该问题的更多信息。

              【讨论】:

                【解决方案15】:

                尝试了上面讨论的几种方法,最终得到了以下工作解决方案,只需复制并粘贴到您的编辑器中即可尝试。要测试只需将哈希更改为收件箱、发件箱、在 url 中撰写并按回车键。

                <html>
                    <head>
                        <link type='text/css' rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css' />
                        <script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
                        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
                    </head>
                    <body>
                        <div class="container body-content">
                            <ul class="nav nav-tabs">
                                <li class="active"><a data-toggle="tab" href="#inbox">Inbox</a></li>
                                <li><a data-toggle="tab" href="#outbox">Outbox</a></li>
                                <li><a data-toggle="tab" href="#compose">Compose</a></li>
                            </ul>
                            <div class="tab-content">
                                <div id="inbox" class="tab-pane fade in active">
                                    Inbox Content
                                </div>
                                <div id="outbox" class="tab-pane fade">
                                    Outbox Content
                                </div>
                                <div id="compose" class="tab-pane fade">
                                    Compose Content
                                </div>
                            </div>
                        </div>
                        <script>
                            $(function () {
                                var hash = window.location.hash;
                                hash && $('ul.nav a[href="' + hash + '"]').tab('show');
                            });
                        </script>
                    </body>
                </html>
                

                希望这会节省您的时间。

                【讨论】:

                  【解决方案16】:

                  这就是我所做的,非常简单,只要你的标签链接有一个与之关联的 ID,你就可以获取 href 属性并将其传递给显示标签内容的函数:

                  <script type="text/javascript">
                          jQuery(document).ready(function() {
                              var hash = document.location.hash;
                              var prefix = "tab_";
                              if (hash) {
                                  var tab = jQuery(hash.replace(prefix,"")).attr('href');
                                  jQuery('.nav-tabs a[href='+tab+']').tab('show');
                              }
                          });
                          </script>
                  

                  然后在您的网址中,您可以将哈希添加为:#tab_tab1,“tab_”部分已从哈希本身中删除,因此导航选项卡 (tabid1) 中实际选项卡链接的 ID 放置在此之后,所以你的网址看起来像:www.mydomain.com/index.php#tab_tabid1。

                  这对我来说很完美,希望对其他人有帮助:-)

                  【讨论】:

                    【解决方案17】:

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

                    $(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);
                      });
                    });

                    【讨论】:

                      【解决方案18】:

                      这是我处理嵌套标签的解决方案。 我刚刚添加了一个功能来检查活动选项卡是否有要激活的父选项卡。 这是函数:

                      function activateParentTab(tab) {
                          $('.tab-pane').each(function() {
                              var cur_tab = $(this);
                              if ( $(this).find('#' + tab).length > 0 ) {
                                  $('.nav-tabs a[href=#'+ cur_tab.attr('id') +']').tab('show');
                                  return false;
                              }
                          });
                      }
                      

                      并且可以这样调用(基于@flynfish的解决方案):

                      var hash = document.location.hash;
                      var prefix = "";
                      if (hash) {
                          $('.nav-tabs a[href='+hash.replace(prefix,"")+']').tab('show');
                          activateParentTab(hash);
                      } 
                      
                      // Change hash for page-reload
                      $('.nav-tabs a').on('shown', function (e) {
                          window.location.hash = e.target.hash.replace("#", "#" + prefix);
                      });
                      

                      这个解决方案目前对我来说很好用。 希望这对其他人有用;)

                      【讨论】:

                        【解决方案19】:

                        我必须修改一些位才能为我工作。 我正在使用 Bootstrap 3 和 jQuery 2

                        // Javascript to enable link to tab
                        var hash = document.location.hash;
                        var prefix = "!";
                        if (hash) {
                            hash = hash.replace(prefix,'');
                            var hashPieces = hash.split('?');
                            activeTab = $('[role="tablist"] a[href=' + hashPieces[0] + ']');
                            activeTab && activeTab.tab('show');
                        }
                        
                        // Change hash for page-reload
                        $('[role="tablist"] a').on('shown.bs.tab', function (e) {
                            window.location.hash = e.target.hash.replace("#", "#" + prefix);
                        });
                        

                        【讨论】:

                        • 很好的答案,除了我必须替换“!”前缀为“tab_”。否则效果很好。
                        【解决方案20】:

                        我刚遇到这个问题,但需要处理多个标签级别。代码相当丑陋(请参阅 cmets),但可以完成它的工作:https://gist.github.com/JensRantil/4721860 希望其他人会发现它有用(并随时提出更好的解决方案!)。

                        【讨论】:

                          【解决方案21】:

                          结合其他答案的部分,这是一个可以打开多层嵌套标签的解决方案:

                          // opens all tabs down to the specified tab
                          var hash = location.hash.split('?')[0];
                          if(hash) {
                            var $link = $('[href=' + hash + ']');
                            var parents = $link.parents('.tab-pane').get();
                            $(parents.reverse()).each(function() {
                              $('[href=#' + this.id + ']').tab('show') ;
                            });
                            $link.tab('show');
                          }
                          

                          【讨论】:

                          • 只适用于 2 层嵌套,第 3 层会导致问题。
                          • 我刚刚针对三个级别的选项卡进行了测试,它似乎对我有用。您确定这不是您的实施问题吗?你遇到了什么“问题”?
                          • 第 1 级和第 2 级中的任何选项卡都可以正常工作,但是,在第 3 级中,刷新页面(或提交表单)时,当页面重新打开时,焦点将集中在第二级的第一个标签。
                          • 所以它工作正常(我的代码中有一个小错字),但是在错字更正之后,只有在代码上方的 javascript 中使用 $('.nav-tabs li a').click( function(e) { history.pushState( null, null, $(this).attr('href') );});
                          【解决方案22】:

                          如果这对任何人都很重要,那么以下代码很小并且可以完美运行,以从 URL 中获取单个哈希值并显示:

                          <script>
                              window.onload = function () {
                                  let url = document.location.toString();
                                  let splitHash = url.split("#");
                                  document.getElementById(splitHash[1]).click();
                              };
                          </script>
                          

                          它的作用是检索 id 并触发 click 事件。很简单。

                          【讨论】:

                            【解决方案23】:

                            我为带有 ajax #!# 的链接(例如/test.com#!#test3)做这样的事情,但你可以随意修改它

                            $(document).ready(function() {
                            
                                   let hash = document.location.hash;
                                   let prefix = "!#";
                            
                                   //change hash url on page reload
                                   if (hash) {
                                     $('.nav-tabs a[href=\"'+hash.replace(prefix,"")+'\"]').tab('show');
                                   } 
                            
                                   // change hash url on switch tab
                                   $('.nav-tabs a').on('shown.bs.tab', function (e) {
                                      window.location.hash = e.target.hash.replace("#", "#" + prefix);
                                   });
                             });
                            

                            简单页面示例on Github here

                            【讨论】:

                              【解决方案24】:

                              我知道这个线程已经很老了,但我会在这里留下我自己的实现:

                              $(function () {
                                // some initialization code
                              
                                addTabBehavior()
                              })
                              
                              // Initialize events and change tab on first page load.
                              function addTabBehavior() {
                                $('.nav-tabs a').on('show.bs.tab', e => {
                                  window.location.hash = e.target.hash.replace('nav-', '')
                                })
                              
                                $(window).on('popstate', e => {
                                  changeTab()
                                })
                              
                                changeTab()
                              }
                              
                              // Change the current tab and URL hash; if don't have any hash
                              // in URL, so activate the first tab and update the URL hash.
                              function changeTab() {
                                const hash = getUrlHash()
                              
                                if (hash) {
                                  $(`.nav-tabs a[href="#nav-${hash}"]`).tab('show')
                                } else {
                                  $('.nav-tabs a').first().tab('show')
                                }
                              }
                              
                              // Get the hash from URL. Ex: www.example.com/#tab1
                              function getUrlHash() {
                                return window.location.hash.slice(1)
                              }
                              

                              请注意,我使用 nav- 类前缀来导航链接。

                              【讨论】:

                                猜你喜欢
                                • 2016-03-16
                                • 1970-01-01
                                • 1970-01-01
                                • 2015-06-23
                                • 2015-01-19
                                • 1970-01-01
                                • 1970-01-01
                                • 2014-12-08
                                相关资源
                                最近更新 更多