Twitterブートストラップタブ:ページの再読み込みまたはハイパーリンクの特定のタブに移動


358

TwitterのBootstrap FrameworkとそのBootstrap Tabs JSを使用しているWebページを開発しています。いくつかのマイナーな問題を除いて、それはうまく機能します。その1つは、外部リンクから特定のタブに直接移動する方法がわからないことです。例えば:

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

外部ページからのリンクをクリックすると、それぞれ[ホーム]タブと[メモ]タブに移動します


49
これが組み込まれたらいいのに!
デイモン

5
この質問もここで取り上げられました:github.com/twitter/bootstrap/issues/2415(そしてそこにいくつかの解決策があります)。
Ztyx 2013


1
ブートストラップの問題への更新されたリンクはgithub.com/twbs/bootstrap/issues/2415
bmihelac

3
これを修正するプラグイン:github.com/timabell/jquery.stickytabs
Tim Abell

回答:


603

これが私の問題の解決策です。おそらく少し遅れます。しかし、それはおそらく他の人を助けることができます:

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

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

83
私は、1つの以上の余分な行を追加したいwindow.scrollTo(0, 0);ことを確認ウィンドウが常にトップにスクロールするために
チュンLê

1
$( '。nav-tabs a [href * =#' + url.split( '#')[1] + ']')。tab( 'show'); // *を使用すると、それ以外の場合は最初の#...とのみ一致するため、より安全です
mattangriffel

1
私のために働いたオンライン:window.location.hash && $( 'li a [href = "' + window.location.hash + '"]')。tab( 'show')。trigger( "click");
Dean Meehan 2014

10
Bootstrap 3のデモは次のとおりです。bootply.com / render / VQqzOawoYc#tab2ソースコード
Zim

2
jqueryを1.09から1.11にアップグレードした後、次のエラーが発生しますSyntax error, unrecognized expression: .nav-tabs a[href=#tab-2]stackoverflow.com/questions/12131273/…
Pietro Z.

213

更新

Bootstrap 3の場合、次のように変更.on('shown', ...)します.on('shown.bs.tab', ....)


これは@dubbeの回答とこのSOが受け入れた回答に基づいています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>

1
特定のタブの下にあるブックマークを参照する簡単な方法はありますか?ページに5つのタブがあり、その下にいくつかのブックマークがあります。これらのブックマークをタブの外からリンクできるようにしたいのですが。
nize

@nizeあなたがしようとしていることでjsfiddleを作成する場合、私は見てみるようにします。
flynfish 2013

1
Bootstrap 3のBootlpyデモは次のとおりです。bootply.com / render / VQqzOawoYc#tab2ソースコード
Zim

上記の例では、hrefの二重引用符が欠落しています。5行目は次のようになります$('.nav-tabs a[href="'+hash.replace(prefix,"")+'"]').tab('show');
Ponyboy

'yoursite.com/anotherpage/#tab_mytab'の最後のフォワードスラッシュ(#の前)を削除する必要があったことを除いて、私にとっては機能します。
アレクサンダー

52

click対応するタブリンクでイベントをトリガーできます。

$(document).ready(function(){

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

});

先端をありがとう!これは1つの小さな問題でうまく機能しました。ページを更新しても、正しいタブに移動しません。Ctrl + F5を押すと、コードを次のように変更しました: `$(document).ready(function(){function getUrlVars(){var vars = {}; var parts = window.location.href.replace(/ [?&] +([ ^ =&] +)=([^&] *)/ gi、function(m、key、value){vars [key] = value;});戻り変数;} var action = getUrlVars()["action" ]; if(action!= ""){$( 'a [href = "#' + action + '"]')。click()};}); `
mraliks '23年

44

これは、スクロールを防ぐダブのソリューションの改善された実装です。

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

21

提供されているJavaScriptソリューションは機能するかもしれませんが、追加のJavaScriptを必要としない少し異なる方法を使用しましたが、ビューにロジックが必要です。次のような標準URLパラメータを使用してリンクを作成します。

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

次に、activeTabの値を検出して、適切な 'class = "active"'を書き込みます。 <li>

疑似コード(ご使用の言語で適宜実装してください)。注この例でパラメーターが指定されていない場合は、「ホーム」タブをデフォルトのアクティブとして設定しています。

$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にジャンプするため、カーソルの位置が上下するためです。
TrungLê2012

私はこの解決策を好みます。実際、私はそれに応じてアクティブクラスを設定することで、タブの新しいルートを作成し、ビューを再生成しました。これにより、ページのサイズ変更、URLハッシュ、ページのスクロールなどの問題を回避できます。
Vijay Meena

10

私は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. [オプション]別のタブを手動で選択した場合はハッシュを更新する

要求されたハッシュへのスクロールは扱いません。しかし、それをすべきですか?



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

1
これは、ブートストラップ3で動作しない、'shown'あるべき'shown.bs.tab'ドキュメントごと:getbootstrap.com/javascript/#tabs-events。理由は
わかりませ

6

このコードは、#hashに応じて適切なタブを選択し、タブがクリックされたときに適切な#hashを追加します。(これはjqueryを使用します)

Coffeescriptで:

$(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を読み込んだ後にそれを置くとうまくいきます。
Ron

6

デミルカンセレビィのソリューションを基に構築。サーバーからページをリロードしなくても、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>


5

@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"が必要です


5

以下のコードで後者の可用性に応じて、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');
    }
});

4

Bootstrapの作者がGitHubの課題追跡に提供しているコードを使用することをお勧めします。

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

問題へのリンクで、彼らがそれをサポートすることを選択しなかった理由に関する詳細情報を見つけることができます。


4

上記の2つの方法を試して、次の実用的な解決策が得られたら、コピーしてエディターに貼り付けてみてください。テストするには、ハッシュを受信トレイ、送信トレイに変更し、URLを作成してEnterキーを押します。

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

これがあなたの時間を節約することを願っています。


3

ここに私がやったこと、本当に簡単です、そしてあなたのタブリンクがそれらに関連付けられた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>

次に、URLに次のようなハッシュを追加できます:#tab_tab1、「tab_」の部分はハッシュ自体から削除されるため、nav-tabs(tabid1)の実際のタブリンクのIDはこの後に配置されます。 URLは次のようになります。www.mydomain.com/ index.php#tab_tabid1。

これは私にとって完璧に動作し、それが他の誰かを助けることを願っています:-)


2

これは、ネストされたタブを処理するための私のソリューションです。アクティブなタブにアクティブ化する親タブがあるかどうかを確認する関数を追加しました。これは関数です:

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

このソリューションは、現時点ではかなりうまく機能しています。これが他の誰かに役立つことを願っています;)


2

これが機能するように、いくつかのビットを変更する必要がありました。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_」を付けます。それ以外の場合は完全に機能しました。
koziez

2

このコードをページに挿入するだけです:

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


1

私はこの問題を抱えていましたが、複数のタブレベルを処理する必要がありました。コードはやや醜いですが(コメントを参照)、その仕事をします:https : //gist.github.com/JensRantil/4721860うまくいけば、他の誰かがそれを見つけてくれるでしょう(そして、より良い解決策を提案してください!)。


1

他の答えからの部分を組み合わせて、ネストされたタブの多くのレベルを開くことができるソリューションは次のとおりです。

// 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番目のレベルでは問題が発生します。
ニコラスハミルトン

これを3つのレベルのタブに対してテストしたところ、うまく機能しているようです。これは実装の問題ではないのですか?どのような「問題」が発生していますか?
cweston 2016

第1レベルと第2レベルのタブはすべて正常に機能しますが、第3レベルでは、ページを更新する(またはフォームを送信する)と、ページが再び開いたときに、第2レベルの最初のタブにフォーカスが移ります。
ニコラスハミルトン

したがって、問題なく動作しました(コードにマイナーな誤植がありました)。ただし、誤植を修正した後は$('.nav-tabs li a').click( function(e) { history.pushState( null, null, $(this).attr('href') );});、コードの上のJavaScript でのみ使用できます。
ニコラスハミルトン

1

誰にとっても重要な場合、次のコードは小さく、完璧に機能し、URLから単一のハッシュ値を取得してそれを示します。

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

IDを取得し、クリックイベントを発生させます。シンプル。


0

私は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);
       });
 });

Githubのシンプルなページの例はこちら


0

私はこのスレッドが非常に古いことを知っていますが、私はここに自分の実装を残します:

$(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-ナビゲーションリンクにクラスプレフィックスを使用していることに注意してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.