Twitter Bootstrap - Sekmeler - URL değişmez


109

Twitter Bootstrap ve "sekmelerini" kullanıyorum.

Takip koduna sahibim:

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

Sekmeler düzgün çalışıyor, ancak URL'deki # ekle, # düzenle, # sil eklenmedi.

data-toggleURL değişikliklerini kaldırdığımda , ancak sekmeler çalışmıyor.

Bunun için herhangi bir çözüm var mı?



Yanıtlar:


269

Bu kodu deneyin. Sayfa yüklemesinde hash'e göre url + açılır sekmesine tab href ekler:

$(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
Çok güzel çalışıyor. +1. Ancak selektörden "hash && $ .." nin nedeni, show sekmesidir, ancak "hash &&" ne anlama gelir? Teşekkürler
richardhell

4
&&araçlar ANDtrue o equates sol eğer öyleyse ( hash0, null veya boş değildir) ve ile gerçek ardından, bir şey yapmak ancak hat uçlarına doğru eşittir ;yüzden önce ilgisi yoktur ;ve bu bir eğer önemli değil sekmesi gösterilir veya gösterilmez ve neyin .tab('show')döndüğü önemli değildir , yine de deneyecektir. Mantığı bu şekilde değerlendirirken, denklemin ilk kısmı (önceki &&) yanlışsa, değerlendirmeye devam etmeye gerek yoktur, bu nedenle sekme gösterilmez. Aynı etkiyi şu şekilde elde edebilirsiniz:if(hash){ $('ul.nav a[href="' + hash + '"]').tab('show'); }
vahanpwns

1
TL; DR: a && b;denemek demektir ave sonra sadece doğruysa deneyin b. Dizeler boş değilse doğrudur.
vahanpwns

8
"#" Url'sini kullandığımda sayfanın yalnızca en üstte yeniden yüklenmesi için bunu nasıl yapabilirim? Şu anda sekmelerin başladığı yere doğru aşağı kaydırılıyor. En üstte asıl sayfaya gitmek istiyorum
kibaekr

1
iyi çalışıyor, ancak "$ ('. nav-tabs a') değiştirmek zorunda kaldı. Bootstrap 3
Zzirconium

49

Tam bir çözüm için gerekli üç bileşen vardır:

  1. URL'de bir karma varsa, sayfa yüklendiğinde doğru sekmeyi gösterin.
  2. Sekme değiştirildiğinde URL'deki karmanın değiştirilmesi.
  3. URL'de karma değiştiğinde sekmeyi değiştirin (geri / ileri düğmeleri) ve ilk sekmenin doğru şekilde çevrildiğinden emin olun.

Buradaki yorumların hiçbirinin veya kabul edilen cevabın tüm bu senaryoları ele aldığını sanmıyorum.

İşin içinde oldukça fazla olduğu için, küçük bir jQuery eklentisi olarak en temiz olduğunu düşünüyorum: https://github.com/aidanlister/jquery-stickytabs

Eklentiyi şu şekilde çağırabilirsiniz:

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

Bunun için bir blog yazısı hazırladım, http://aidanlister.com/2014/03/persisting-the-tab-state-in-bootstrap/


Ona kendi git deposu verdim : github.com/timabell/jquery.stickytabs - eklenti için çok teşekkürler, bir zevk.
Tim Abell

@Tomaszback'in çözümünün çalışmadığı geri / sonraki taramada da çalıştığı için bu çözüm için +1. Teşekkürler!
bitfidget

Bu harika ve iyi çalışıyor, ancak sayfayı URL'de bir karma ile yüklediğimde değil. Yanlış yaptığım bir şey olduğundan emin olmak için araştırmaya devam edecek (büyük olasılıkla) Ancak, ona +1 vereceğim
MattBoothDev

27

Kullanmak eklentinin sekmeleri işlemesini data-toggle="tab" ister , bu sırada preventDefaultolayda çağırır ( kod github'da ).

Kendi sekme etkinleştirmenizi kullanabilir ve etkinliğin geçmesine izin verebilirsiniz:

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

Ve özniteliği kaldırmalısınız data-toggle="tab"

Şüpheniz varsa dokümanı kontrol edin .


11

Bağlantı öğeleriniz url karmasını zaten değiştirdiğinden, onhashchange olayını dinlemek başka bir iyi seçenektir. @Flori'nin daha önce de bahsettiği gibi, bu yöntem tarayıcı geri düğmesiyle iyi çalışıyor.

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

Son olarak, dinleyiciyi tanımladıktan hemen sonra olayı tetiklemek, sayfa yüklemesinde doğru sekmeyi göstermeye de yardımcı olacaktır.


3

Sorununuza çözümüm:

Öncelikle data-valueher abağlantıya aşağıdaki gibi yeni öznitelik ekleyin :

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

İkinci olarak, sekme kimliklerini değiştirin, örneğin 'den' adde tab-add, href'leri de tab-önek içerecek şekilde güncelleyin :

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

Ve son olarak js kodu:

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

İşte jsFiddle - ancak jsFiddle tarafından kullanılan iframe nedeniyle çalışmıyor, ancak çözümümün kaynağını okuyabilirsiniz.


3

Bootstrap 3 Tabs ile CakePHP ile aynı sorun, ayrıca harici URL ve çapa ile gönderdiğimde menümü kaybederek bölüme atlıyor, birçok çözümü inceledikten sonra bunu yaptı ...

teşekkürler: 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

Ayrıca hash değişikliklerine tepki vermenin basit bir yolu vardır (örneğin geri düğmesi). Tomaszbak çözümüne bir hashchange olay dinleyicisi eklemeniz yeterlidir:

$(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. * Kullanıyorum ve yukarıdaki çözümlerden hiçbiri bana yardımcı olmadı, hatta yanıt olarak işaretlendi. Senaryoyu aşağıya ekledim ve çalıştım.

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

Umarım bu size yardımcı olur.


0

En basit, buradadata-toggle="tab" açıklanan belgelenmiş sözdizimini kullandığınızı varsayarsak :

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

Bu, URL'yi değiştirir, ancak belirli bir sekmeyi açmak için bir bağlantıya tıklandığında oraya gidemez
Khrys

0

Ruby on Rails veya başka bir sunucu tarafı komut dosyasını kullananlar için, bu anchorseçeneği yollarda kullanmak isteyeceksiniz . Bunun nedeni, sayfa bir kez yüklendiğinde, kullanılabilir URL karmasının olmamasıdır. Bağlantınız veya form gönderiminiz yoluyla doğru sekmeyi sağlamak isteyeceksiniz.

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

Pencerenin kimliğe atlamasını önlemek için bir önek kullanıyorsanız:

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

O zaman siz 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

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

Bu Bootstrap 3'te çalışmalıdır.


0

Orijinal çözüm için @tomaszbak'a teşekkürler, ancak düzenlemelerim reddedildiğinden ve henüz onun gönderisine yorum yapamadığım için biraz geliştirilmiş ve daha okunabilir versiyonumu burada bırakacağım.

Temelde aynı şeyi yapıyor, ancak tarayıcılar arası uyumluluk sorununu düzeltirse, onunla yaşadığım.

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

Reddedildi benim için çalışmıyordu (belki sadece Firefox versiyonuydu). Her neyse, var scrollmem = $ ('body'] için değişiklik yaptım. ScrollTop () || $ ( 'html') scrollTop ().; Teşekkürler!
tomaszbak

1
Evet. Bunun bir tarayıcı şeyi olduğunu anladığımı ve emin olmak için hızla Chrome'a ​​girdiğimi söylediğin anda bana bundan bahset. Keşke incelemelerin düzenlenmesine yorum yapmanın bir yolu olsaydı.
Fuxy

0

İşte kullanan bir seçenek history.pushState, bir önceki sekmeye geri dönmek için tarayıcı geçmişini kullanabilmesi

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

Yukarıdakilerin hiçbiri benim için işe yaramadı, işte benimkini nasıl çalıştırdım:

  1. class="tab-link"Bu işlevselliğe ihtiyaç duyan tüm bağlantılara ekleyin
  2. Aşağıdaki kodu javascript'inize ekleyin:
    window.addEventListener
    (
        'Popstate',
        işlev (olay)
        {
            tab_change ();
        }
    );

    function tab_change ()
    {
        var hash = window.location.hash;
        hash && $ ('ul.nav a [href = "' + hash + '"]') .tab ('göster');

        $ ('.tab-link']. tıklayın
        (
            işlev (e)
            {
                $ (bu) .tab ['göster');

                var scrollmem = $ ['gövde'] .scrollTop () || $ ('html'] .scrollTop ();
                window.location.hash = this.hash;
                $ ('html, gövde'] .scrollTop (scrollmem);

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


0

OP'nin JQuery kullandığını söylediğini anladım, ancak bunu yapmak için vanilla JS'yi kullanabilirsiniz:

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

-2

Bu aynı zamanda jquery ve bootstrap kullanılırken href'in çalışmadığı son derece belirsiz bir sekmeyi de düzeltir.

<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 Bu cevabın 3 Ay önce cevapta tam olarak aynı kodla verilen önceki cevaplara nasıl bir değer kattığını görmüyorum. Bu nedenle bence faydalı bir cevap değil.
Hayır
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.