Twitterブートストラップ-タブ-URLは変更されません


109

私はTwitter Bootstrapとその「タブ」を使用しています。

私は次のコードを持っています:

<ul class="nav nav-tabs">
    <li class="active"><a data-toggle="tab" href="#add">add</a></li>
    <li><a data-toggle="tab" href="#edit" >edit</a></li>
    <li><a data-toggle="tab" href="#delete" >delete</a></li>
</ul>

タブは適切に機能しますが、URLの#add、#edit、#deleteは追加されません。

data-toggleURLの変更を削除したが、タブが機能しない。

これに対する解決策はありますか?


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

回答:


269

このコードを試してください。これは、urlにtab hrefを追加し、ページ読み込み時のハッシュに基づいてタブを開きます。

$(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() || $('html').scrollTop();
    window.location.hash = this.hash;
    $('html,body').scrollTop(scrollmem);
  });
});

1
それはとてもうまくいきます。+1。しかし、セレクターからの「ハッシュ&& $ ..」の理由はタブの表示ですが、「ハッシュ&&」の意味は何ですか。ありがとう
richardhell 2013年

4
&&つまりAND、その左側がtrue(hash0、null、または空ではない)に等しく、右側がtrueに等しい場合は、何かを実行しますが、行がaで終わっている;ため、前に何もする必要;がなく、タブが表示されているかいないか.tab('show')は関係なく、何が戻るかは関係ありません。この方法でロジックを評価するとき、方程式の最初の部分(before &&)がfalseの場合、評価を続ける必要がないため、タブは表示されません。:あなたはこのように同じ効果が達成できるif(hash){ $('ul.nav a[href="' + hash + '"]').tab('show'); }
vahanpwns

1
TL; DR:a && b;試行することを意味しa、真の場合のみ試行するb。空でない場合、文字列はtrueです。
vahanpwns 2014

8
「#」URLを使用したときに上部のページがリロードされるようにするにはどうすればよいですか?現在、タブが始まる場所までスクロールダウンしています。実際のページまで上にスクロールしたいのですが
kibaekr

1
正常に動作しますが、Bootstrap 3
Zzirconium

49

完全なソリューションには3つのコンポーネントが必要です。

  1. URLにハッシュがある場合、ページが読み込まれたときに正しいタブを表示します。
  2. タブが変更されたときにURLのハッシュを変更する。
  3. URLのハッシュが変更されたときにタブを変更し(戻る/進むボタン)、最初のタブが正しく循環していることを確認します。

ここのコメントも、受け入れられた答えも、これらのシナリオをすべて処理するとは思いません。

かなり関与しているので、小さなjQueryプラグインとして最も近いと思います:https : //github.com/aidanlister/jquery-stickytabs

次のようにプラグインを呼び出すことができます:

$('.nav-tabs').stickyTabs();

私はこれのためにブログ投稿をしました、http://aidanlister.com/2014/03/persisting-the-tab-state-in-bootstrap/


私はそれをそれ自身のgit repoであるgithub.com/timabell/jquery.stickytabsに与えました -プラグインに感謝します。
Tim Abell、2014年

このソリューションの+1。@ tomaszback 'ソリューションでは機能しないバック/次のブラウジングでも機能します。ありがとう!
bitfidget 2015年

これはすばらしい方法でうまく機能しますが、URLにハッシュが含まれているページをロードした場合はそうではありません。それが私が間違っていることを確認するために掘り続けます(可能性が高い)。ただし、+ 1を付けます
MattBoothDev

27

を使用data-toggle="tab" すると、プラグインがタブを処理するように要求されます。タブの処理中preventDefaultに、イベントが呼び出されます(githubのコード)。

独自のタブアクティベーションを使用して、イベントを通過させることができます。

$('.nav-tabs a').click(function (e) {
    // No e.preventDefault() here
    $(this).tab('show');
});

そして、あなたは属性を削除する必要があります data-toggle="tab"

疑問がある場合は、ドキュメントを確認してください。


11

アンカー要素はすでにURLハッシュを変更しているため、onhashchangeイベントをリッスンすることも別の優れたオプションです。@floriが既に述べたように、この方法はブラウザの戻るボタンでうまく機能します。

var tabs$ = $(".nav-tabs a");

$( window ).on("hashchange", function() {
    var hash = window.location.hash, // get current hash
        menu_item$ = tabs$.filter('[href="' + hash + '"]'); // get the menu element

    menu_item$.tab("show"); // call bootstrap to show the tab
}).trigger("hashchange");

最後に、リスナーを定義した直後にイベントをトリガーすると、ページの読み込み時に正しいタブを表示するのにも役立ちます。


3

あなたの問題に対する私の解決策:

まず、次のようdata-valueに各aリンクに新しい属性を追加します。

<ul class="nav nav-tabs">
    <li class="active">
        <a data-toggle="tab" href="#tab-add" data-value="#add">add</a>
    </li>
    <li>
        <a data-toggle="tab" href="#tab-edit" data-value="#edit">edit</a>
    </li>
    <li>
        <a data-toggle="tab" href="#tab-delete" data-value="#delete">delete</a>
    </li>
</ul>

第二に、タブ、例えばからの変更ID addtab-addも、更新のhrefを含めるには、tab-接頭辞:

<div class="tab-content">
    <div class="tab-pane" id="tab-add">Add panel</div>
    <div class="tab-pane" id="tab-edit">Edit panel</div>
    <div class="tab-pane" id="tab-delete">Panel panel</div>
</div>

そして最後にjsコード:

<script type="text/javascript">
    $(function () {
        var navTabs = $('.nav-tabs a');
        var hash = window.location.hash;
        hash && navTabs.filter('[data-value="' + hash + '"]').tab('show');

        navTabs.on('shown', function (e) {
            var newhash = $(e.target).attr('data-value');
            window.location.hash = newhash;
        });
    })
</script>

ここにjsFiddleがあります-jsFiddleで使用されているiframeのために機能しませんが、私のソリューションのソースを読むことができます。


3

Bootstrap 3タブを使用したCakePHPでの同じ問題に加えて、外部URLとアンカーを使用して送信すると、多くの解決策を確認した後、メニューが失われるセクションにジャンプします...

おかげで:http : //ck.kennt-wayne.de/2012/dec/twitter-bootstrap-how-to-fix-tabs

$(document).ready(function()
 {  
//Redirecciona al tab, usando un prefijo al cargar por primera vez, al usar redirect en cake #_Pagos    
//Redirecciona al tab, usando #Pagos
/* Automagically jump on good tab based on anchor; for page reloads or links */
 if(location.hash) 
  {
     $('a[href=' + location.hash + ']').tab('show');         
  }


//Para evitar el bajar al nivel del tab, (al mostrarse el tab subimos)
$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) 
{
    location.hash = $(e.target).attr('href').substr(1);
    scrollTo(0,0);      
});



//Actualiza el URL con el anchor o ancla del tab al darle clic
 /* Update hash based on tab, basically restores browser default behavior to
 fix bootstrap tabs */
$(document.body).on("click", "a[data-toggle]", function(event) 
  {
    location.hash = this.getAttribute("href");
  });


//Redirecciona al tab, al usar los botones de regresar y avanzar del navegador.
/* on history back activate the tab of the location hash if exists or the default tab if no hash exists */   
$(window).on('popstate', function() 
{
  //Si se accesa al menu, se regresa al tab del perfil (activo default), fixed conflict with menu
  //var anchor = location.hash || $("a[data-toggle=tab]").first().attr("href");
  var anchor = location.hash;
  $('a[href=' + anchor + ']').tab('show');

});   

});//Fin OnReady

2

ハッシュの変更に対応する簡単な方法もあります([戻る]ボタンなど)。hashchangeイベントリスナーをtomaszbakソリューションに追加するだけです。

$(function(){
  // Change tab on load
  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);
  });

  // Change tab on hashchange
  window.addEventListener('hashchange', function() {
    var changedHash = window.location.hash;
    changedHash && $('ul.nav a[href="' + changedHash + '"]').tab('show');
  }, false);
});

1

私はBootstrap 3.3。*を使用していますが、上記の解決策はどれも役に立たず、回答1としてマークされていました。以下のスクリプトを追加して作業しました。

$(function(){
    var hash = document.location.hash;
    if (hash) {
       $('.navbar-nav a[href="' + hash + '"]').tab('show');
    }
    $('a[data-toggle="tab"]').on('click', function (e) {
       history.pushState(null, null, $(this).attr('href'));
    });
});

これがお役に立てば幸いです。


0

ここでdata-toggle="tab"説明する文書化された構文を使用していると仮定すると、最も単純です。

$(document).on('shown.bs.tab', function(event) {
  window.location.hash = $(event.target).attr('href');
});

これによりURLは変更されますが、リンクをクリックして特定のタブを開くと、そこに移動できません
Khrys

0

Ruby on Railsまたはその他のサーバー側スクリプトを使用しているanchor場合は、パスでオプションを使用する必要があります。これは、ページが読み込まれると、利用可能なURLハッシュがないためです。リンクまたはフォーム送信を介して正しいタブを提供する必要があります。

<%= form_for @foo, url: foo_path(@foo, anchor: dom_id(foo)) do |f| %>
# Or
<%= link_to 'Foo', foo_path(@foo, anchor: dom_id(foo)) %>

ウィンドウがIDにジャンプしないようにするためにプレフィックスを使用している場合:

<%= form_for @foo, url: foo_path(@foo, anchor: "bar_#{dom_id(foo)}") do |f| %>

次に、CoffeeScript:

  hash = document.location.hash
  prefix = 'bar_'
  $('.nav-tabs a[href=' + hash.replace(prefix, '') + ']').tab 'show' if hash
  $('.nav-tabs a').on 'shown.bs.tab', (e) ->
    window.location.hash = e.target.hash.replace '#', '#' + prefix

またはJavaScript:

var hash, prefix;

hash = document.location.hash;
prefix = 'bar_';

if (hash) {
  $('.nav-tabs a[href=' + hash.replace(prefix, '') + ']').tab('show');
}

$('.nav-tabs a').on('shown.bs.tab', function(e) {
  window.location.hash = e.target.hash.replace('#', '#' + prefix);
});

これはBootstrap 3で動作するはずです。


0

元の解決策を提供してくれた@tomaszbakに感謝します。ただし、編集が拒否され、彼の投稿にコメントできないため、少し改善された読みやすいバージョンをここに残します。

基本的に同じことを行いますが、ブラウザ間の互換性の問題を修正した場合、私は彼と一緒に問題を抱えていました。

$(document).ready(function(){
   // go to hash on window load
   var hash = window.location.hash;
   if (hash) {
       $('ul.nav a[href="' + hash + '"]').tab('show');
   }
   // change hash on click
   $('.nav-tabs a').click(function (e) {
       $(this).tab('show');
       if($('html').scrollTop()){
           var scrollmem = $('html').scrollTop(); // get scrollbar position (firefox)
       }else{
           var scrollmem = $('body').scrollTop(); // get scrollbar position (chrome)
       }
       window.location.hash = this.hash;
       $('html,body').scrollTop(scrollmem); // set scrollbar position
   });
});

拒否は機能しませんでした(たぶんFirefoxのバージョンだったのでしょう)。とにかく、var scrollmem = $( 'body')。scrollTop()||に変更を加えました。$( 'html')。scrollTop(); ありがとう!
tomaszbak 2016年

1
はい。私がそれがブラウザのことだと気付いた瞬間に、それを確認するためにChromeにすぐに入りました。編集レビューにコメントする方法があったらいいのにと思います。
Fuxy

0

history.pushStateブラウザの履歴を使用して前のタブに戻ることができるように使用するオプションは次のとおりです

  $(document).ready(function() {
  // add a hash to the URL when the user clicks on a tab
  $('a[data-toggle="tab"]').on('click', function(e) {
    history.pushState(null, null, $(this).attr('href'));
  });
  // navigate to a tab when the history changes
  window.addEventListener("popstate", function(e) {
    var activeTab = $('[href=' + location.hash + ']');
    if (activeTab.length) {
      activeTab.tab('show');
    } else {
      $('.nav-tabs a:first').tab('show');
    }
  });
});

0

上記のどれも私にとってうまくいかなかったので、これが私が私の仕事をした方法です:

  1. class="tab-link"この機能を必要とするすべてのリンクに追加
  2. 次のコードをJavaScriptに追加します。
    window.addEventListener
    (
        'ポップステート'、
        関数(イベント)
        {
            tab_change();
        }
    );

    function tab_change()
    {
        var hash = window.location.hash;
        ハッシュ&& $( 'ul.nav a [href = "' + hash + '"]')tab( 'show');

        $( '.tab-link').click
        (
            関数(e)
            {
                $(this).tab( 'show');

                var scrollmem = $( 'body').scrollTop()|| $( 'html').scrollTop();
                window.location.hash = this.hash;
                $( 'html、body').scrollTop(scrollmem);

                $( 'ul.nav-tabs a [href = "' + window.location.hash + '"]').tab( 'show');
            }
        );
    }


0

OPがJQueryを使用すると言っていることを理解しましたが、バニラJSを使用してそれを行うことができます

document.querySelectorAll('ul.nav a.nav-link').forEach(link => {
    link.onclick = () => window.history.pushState(null, null, link.attributes.href.value);
});

-2

これにより、jqueryとブートストラップを使用したときに、a hrefが起動しない非常に不明瞭なタブも修正されます

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> 

<script type="text/javascript">
$('.nav-tabs a').click(function (e) {
    // No e.preventDefault() here.
    $(this).tab('show');
});
</script>

<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/js/bootstrap.min.js"></script>

5
-1この回答が、3か月前に与えられた以前の回答にまったく同じコードを使用してどのように価値を追加するのかわかりません。したがって、私の控えめな見解では、有用な答えではありません。
いいえ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.