Twitter Bootstrap - Tab - URL tidak berubah

109

Saya menggunakan Twitter Bootstrap dan "tab" -nya.

Saya memiliki kode berikut:

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

Tab bekerja dengan baik, tetapi di URL tidak ditambahkan #add, #edit, #delete.

Saat saya menghapus data-toggleURL berubah, tetapi tab tidak berfungsi.

Ada solusi untuk ini?

Ivanka Todorova
sumber
1
Plugin yang memperbaiki ini: github.com/timabell/jquery.stickytabs
Tim Abell
Ini adalah pertanyaan yang mirip dengan stackoverflow.com/q/18999501/873282
koppor

Jawaban:

269

Coba kode ini. Itu menambahkan tab href ke url + membuka tab berdasarkan hash pada pemuatan halaman:

$(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);
  });
});
tomaszbak.dll
sumber
1
Ini bekerja dengan sangat baik. +1. Tapi apa alasan "hash && $ .." dari selector adalah tab show, tapi yang dimaksud dengan "hash &&". Terima kasih
richardhell
4
&&Artinya, ANDjika kiri yang sama dengan benar ( hashbukan 0, nol atau kosong) dan kanan sama dengan benar maka lakukan sesuatu, namun baris diakhiri dengan ;jadi tidak ada yang harus dilakukan sebelumnya ;dan tidak masalah jika a tab ditampilkan atau tidak dan tidak peduli apa yang .tab('show')dikembalikan, itu akan tetap mencoba. Saat mengevaluasi logika dengan cara ini, jika bagian pertama dari persamaan (sebelum &&) salah, Anda tidak perlu melanjutkan evaluasi, sehingga tab tidak akan ditampilkan. Anda dapat mencapai efek yang sama seperti ini:if(hash){ $('ul.nav a[href="' + hash + '"]').tab('show'); }
vahanpwns
1
TL; DR: a && b;berarti coba adan hanya jika itu benar, coba b. String bernilai true jika tidak kosong.
vahanpwns
8
Bagaimana cara membuatnya sehingga laman tersebut dimuat ulang di bagian atas saat saya menggunakan url "#"? Sekarang ini menggulir ke bawah ke tempat tab dimulai. Saya hanya ingin menggulir ke atas ke halaman yang sebenarnya
kibaekr
1
berfungsi dengan baik tetapi harus mengganti "$ ('. nav-tabs a'). click (" by "$ ('# navtabs a'). on ('shown.bs.tabs," pada Bootstrap 3
Zzirconium
49

Ada tiga komponen yang diperlukan untuk solusi lengkap:

  1. Tampilkan tab yang benar saat halaman dimuat jika ada hash di URL.
  2. Mengubah hash di URL saat tab diubah.
  3. Ubah tab saat hash berubah di URL (tombol mundur / maju), dan pastikan tab pertama diputar dengan benar.

Saya pikir tidak ada komentar di sini, atau jawaban yang diterima, menangani semua skenario ini.

Karena ada cukup banyak yang terlibat, saya pikir ini paling rapi sebagai plugin jQuery kecil: https://github.com/aidanlister/jquery-stickytabs

Anda dapat memanggil plugin seperti ini:

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

Saya telah membuat entri blog untuk ini, http://aidanlister.com/2014/03/persisting-the-tab-state-in-bootstrap/

Aidan
sumber
Saya memberikannya sendiri repo git: github.com/timabell/jquery.stickytabs - terima kasih banyak untuk pluginnya, bekerja dengan baik.
Tim Abell
+1 untuk solusi ini karena juga berfungsi pada penjelajahan kembali / berikutnya yang tidak dapat dilakukan oleh solusi @tomaszback. Terima kasih!
bitfidget
Ini bagus dan berfungsi dengan baik, tetapi tidak ketika saya memuat halaman dengan hash di URL. Akan terus menggali untuk memastikan itu adalah sesuatu yang saya lakukan salah (kemungkinan besar). Namun, saya akan memberikannya +1
MattBoothDev
27

Menggunakan data-toggle="tab" meminta plugin untuk menangani tab, yang saat melakukannya akan memanggil preventDefaultacara ( kode di github ).

Anda dapat menggunakan aktivasi tab Anda sendiri, dan membiarkan acara berjalan:

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

Dan Anda harus menghapus atribut tersebut data-toggle="tab"

Periksa dokumennya jika Anda ragu.

Sherbrow
sumber
11

Karena elemen jangkar Anda sudah mengubah hash url, mendengarkan acara onhashchange adalah pilihan bagus lainnya. Seperti yang telah disebutkan @flori, metode ini berfungsi dengan baik dengan tombol kembali di browser.

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

Terakhir, memicu acara tepat setelah Anda menentukan pendengar juga akan membantu menampilkan tab yang tepat saat pemuatan halaman.

halilb
sumber
3

Solusi saya untuk masalah Anda:

Pertama tambahkan data-valueatribut baru ke setiap atautan, seperti ini:

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

Kedua, ubah id tab, misalnya dari addmenjadi tab-add, juga perbarui href untuk menyertakan tab-awalan:

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

Dan akhirnya kode 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>

Ini adalah jsFiddle - tetapi tidak berfungsi karena iframe digunakan oleh jsFiddle, tetapi Anda dapat membaca sumber solusi saya.

psulek
sumber
3

Masalah yang sama dengan CakePHP dengan Tab Bootstrap 3, ditambah lagi ketika saya mengirim dengan URL eksternal dan jangkar, ia melompat ke bagian kehilangan menu saya, setelah meninjau banyak solusi membuat ini ...

terima kasih kepada: 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
Henry Gabriel González Montejo
sumber
2

Ada juga cara sederhana untuk bereaksi pada perubahan hash (misalnya tombol kembali). Cukup tambahkan event listener hashchange ke solusi 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);
});
Flori
sumber
1

Saya menggunakan Bootstrap 3.3. * Dan tidak ada solusi di atas yang membantu saya, bahkan ditandai sebagai jawaban satu. Saya baru saja menambahkan skrip di bawah ini dan bekerja.

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

Semoga ini bisa membantu Anda.

Abimanyu
sumber
0

Paling sederhana, dengan asumsi Anda menggunakan data-toggle="tab"sintaks terdokumentasi yang dijelaskan di sini :

$(document).on('shown.bs.tab', function(event) {
  window.location.hash = $(event.target).attr('href');
});
Fred
sumber
Ini mengubah URL tetapi tidak bisa pergi ke sana ketika mengklik tautan untuk membuka tab tertentu
Khrys
0

Bagi mereka yang menggunakan Ruby on Rails atau skrip sisi server lainnya, Anda akan ingin menggunakan anchoropsi di jalur. Ini karena setelah halaman dimuat, hash URL-nya tidak tersedia. Anda akan ingin memberikan tab yang benar melalui tautan atau pengiriman formulir Anda.

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

Jika Anda menggunakan awalan untuk mencegah jendela melompat ke id:

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

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

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

Ini harus bekerja di Bootstrap 3.

Muhammad
sumber
0

Terima kasih kepada @tomaszbak untuk solusi aslinya namun karena suntingan saya ditolak dan saya tidak dapat mengomentari kirimannya, saya akan meninggalkan versi saya yang sedikit lebih baik dan lebih mudah dibaca di sini.

Itu pada dasarnya melakukan hal yang sama tetapi jika memperbaiki masalah kompatibilitas lintas browser yang saya miliki dengannya.

$(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
   });
});
Fuxy
sumber
Ditolak tidak berfungsi untuk saya (mungkin itu hanya versi Firefox). Pokoknya, saya membuat perubahan ke var scrollmem = $ ('body'). ScrollTop () || $ ('html'). scrollTop (); Terima kasih!
tomaszbak
1
Iya. Ceritakan tentang hal itu saat Anda mengatakan bahwa saya menyadari itu adalah masalah browser dan dengan cepat masuk ke chrome untuk memastikannya. Saya yakin berharap ada cara untuk mengomentari edit ulasan.
Fuxy
0

Berikut adalah opsi yang digunakan history.pushStatesehingga Anda dapat menggunakan riwayat browser Anda untuk kembali ke tab sebelumnya

  $(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');
    }
  });
});
Adam Hei
sumber
0

Tak satu pun di atas berhasil untuk saya, jadi inilah cara saya membuat saya bekerja:

  1. Tambahkan class="tab-link"ke semua tautan yang membutuhkan fungsi ini
  2. Tambahkan kode berikut ke javascript Anda:
    window.addEventListener
    (
        'popstate',
        fungsi (acara)
        {
            tab_change ();
        }
    );

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

        $ ('.tab-link'). klik
        (
            fungsi (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');
            }
        );
    }

simonl
sumber
0

Saya mengerti bahwa OP mengatakan menggunakan JQuery tetapi Anda cukup menggunakan vanilla JS untuk melakukan itu:

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

Ini juga memperbaiki tab yang sangat tidak jelas a href yang tidak aktif saat menggunakan jquery dan bootstrap

<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>
sinar
sumber
5
-1 Saya tidak melihat bagaimana jawaban ini menambahkan nilai apa pun ke jawaban sebelumnya yang diberikan 3 Bulan lalu dengan kode yang sama persis di jawaban. Oleh karena itu, bukan jawaban yang berguna menurut pendapat saya.
Tidak