Tab Bootstrap Twitter: Buka Tab Tertentu pada Reload Halaman atau Hyperlink

358

Saya sedang mengembangkan halaman web di mana saya menggunakan Bootstrap Framework Twitter dan Bootstrap Tabs JS mereka . Ini berfungsi dengan baik kecuali untuk beberapa masalah kecil, salah satunya adalah saya tidak tahu bagaimana masuk langsung ke tab tertentu dari tautan eksternal. Sebagai contoh:

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

harus pergi ke tab Beranda dan tab Catatan masing-masing ketika mengklik tautan dari halaman eksternal

mraliks
sumber
49
berharap ini dibangun!
Damon
5
Pertanyaan ini juga telah diajukan di sini: github.com/twitter/bootstrap/issues/2415 (dan memiliki beberapa solusi di sana).
Ztyx
ini membantu saya -> stackoverflow.com/questions/12131273/...
JGilmartin
1
Tautan yang diperbarui untuk masalah bootstrap adalah github.com/twbs/bootstrap/issues/2415
bmihelac
3
Plugin yang memperbaiki ini: github.com/timabell/jquery.stickytabs
Tim Abell

Jawaban:

603

Ini solusi saya untuk masalah ini, mungkin agak terlambat. Tapi itu mungkin bisa membantu orang lain:

// 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;
})
dubbe
sumber
83
Saya akan menambahkan 1 baris tambahan lagi window.scrollTo(0, 0);untuk memastikan bahwa Window selalu menggulir ke atas
Trung Lê
1
$ ('. nav-tabs a [href * = #' + url.split ('#') [1] + ']'). tab ('show'); // Dengan * lebih aman karena jika tidak, itu hanya cocok dengan # pertama ...
mattangriffel
1
Daring yang berfungsi untuk saya: window.location.hash && $ ('li a [href = "' + window.location.hash + '"]'). Tab ('show'). Trigger ("click");
Dean Meehan
10
Berikut ini adalah demo untuk Bootstrap 3: bootply.com/render/VQqzOawoYc#tab2 dan kode sumber
Zim
2
Setelah jquery upgrade ke 1,11 dari 1,09 saya mendapatkan error ini: Syntax error, unrecognized expression: .nav-tabs a[href=#tab-2]. Dipecahkan menggunakan stackoverflow.com/questions/12131273/...
Pietro Z.
213

MEMPERBARUI

Untuk Bootstrap 3, ubah .on('shown', ...)ke.on('shown.bs.tab', ....)


Ini didasarkan pada jawaban @dubbe dan jawaban yang diterima SO ini . Ini menangani masalah dengan window.scrollTo(0,0)tidak berfungsi dengan benar. Masalahnya adalah ketika Anda mengganti tab hasl pada url yang ditampilkan, browser akan menggulir ke hash itu karena merupakan elemen pada halaman. Untuk menyiasatinya, tambahkan awalan sehingga hash tidak mereferensikan elemen halaman yang sebenarnya

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

Contoh penggunaan

Jika Anda memiliki tab-pane dengan id = "mytab" Anda harus meletakkan tautan Anda seperti ini:

<a href="yoursite.com/#tab_mytab">Go to Specific Tab </a>
flynfish
sumber
1
Apakah akan ada cara sederhana untuk referensi bookmark yang terletak di bawah tab tertentu? Saya memiliki lima tab pada halaman saya, dan di bawah itu saya memiliki sejumlah bookmark. Yang saya inginkan adalah membuat bookmark ini ditautkan dari luar tab.
nize
@nize jika Anda membuat jsfiddle dengan apa yang Anda coba lakukan, saya akan mencoba untuk melihatnya.
flynfish
1
Berikut ini adalah demo Bootlpy untuk Bootstrap 3: bootply.com/render/VQqzOawoYc#tab2 dan kode sumber
Zim
Contoh di atas tidak memiliki tanda kutip ganda pada href. baris 5 seharusnya:$('.nav-tabs a[href="'+hash.replace(prefix,"")+'"]').tab('show');
Ponyboy
Bekerja untuk saya kecuali bahwa saya harus menghapus garis miring terakhir (sebelum #) di 'yoursite.com/anotherpage/#tab_mytab' jika tidak, akan terjadi malapetaka dengan memuat halaman.
Alexander
52

Anda dapat memicu clickacara di tautan tab yang sesuai:

$(document).ready(function(){

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

});
Marian Theisen
sumber
Terima kasih atas tipnya! Ini bekerja sangat baik dengan satu masalah kecil. Menyegarkan halaman, tidak akan membawanya ke tab yang benar. Menekan Ctrl + F5 akan. Saya memodifikasi kode sebagai berikut: `$ (dokumen). Sudah (function () {function getUrlVars () {var vars = {}; var parts = window.location.href.replace (/ [? &] + ([ ^ = &] +) = ([^ &] *) / gi, fungsi (m, kunci, nilai) {vars [key] = value;}); return vars;} var action = getUrlVars () ["action" ]; if (action! = "") {$ ('a [href = "#' + action + '"]'). klik ()};}); `
mraliks
44

Ini adalah implementasi yang ditingkatkan dari solusi dubbe yang mencegah pengguliran.

// 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
    }
})
Demircan Celebi
sumber
21

Sementara solusi JavaScript yang disediakan dapat berfungsi, saya menggunakan cara yang sedikit berbeda yang tidak memerlukan JavaScript tambahan, tetapi memang membutuhkan logika dalam pandangan Anda. Anda membuat tautan dengan parameter URL standar, seperti:

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

Kemudian Anda cukup mendeteksi nilai activeTab untuk menulis 'class = "active"' yang sesuai <li>

Kodesemu (implementasikan sesuai dalam bahasa Anda). Catatan Saya telah menetapkan tab 'beranda' sebagai aktif default jika tidak ada parameter yang diberikan dalam contoh ini.

$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>
Peter
sumber
Saya lebih suka solusi Anda ke solusi JS karena satu alasan sederhana adalah lokasi JS.hash akan melompat ke ID yang menyebabkan posisi kursor naik dan turun.
Trung Lê
Saya lebih suka solusi ini. Bahkan, saya membuat rute baru untuk tab dan tampilan yang dihasilkan kembali dengan mengatur kelas aktif yang sesuai. Ini menghindari sakit kepala ukuran halaman, hash url dan menggulir halaman bersama-sama.
Vijay Meena
10

Saya bukan penggemar if ... else; jadi saya mengambil pendekatan yang lebih sederhana.

$(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. Pilih tab default (biasanya yang pertama)
  2. Beralih ke tab (jika elemen seperti itu memang ada; biarkan jQuery menanganinya); Tidak ada yang terjadi jika hash yang salah ditentukan
  3. [Opsional] Perbarui hash jika tab lain dipilih secara manual

Tidak membahas pengguliran ke hash yang diminta; tetapi haruskah itu?

kunjungan b
sumber
8

Ini berfungsi di Bootstrap 3 dan meningkatkan 2 jawaban teratas dubbe dan flynfish dengan mengintegrasikan jawaban GarciaWebDev juga (yang memungkinkan parameter url setelah hash dan langsung dari penulis Bootstrap pada pelacak masalah github):

// 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);
});
greggdavis
sumber
1
ini tidak berfungsi di Bootstrap 3, 'shown'harus 'shown.bs.tab'sesuai dengan dokumen: getbootstrap.com/javascript/#tabs-events . Saya bingung mengapa tetapi ketika saya mencoba mengedit posting Anda ditolak ...
YPCrumble
6

Kode ini memilih tab kanan tergantung pada hash # dan menambahkan # hash kanan ketika tab diklik. (ini menggunakan jquery)

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

atau di 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);
    });
});
Sucrenoir
sumber
pastikan untuk meletakkan ini setelah jquery dimuat. Saya meletakkannya di tengah-tengah halaman (itu adalah tempat yang mudah untuk memasukkannya untuk pengujian) dan tidak berhasil. Menempatkannya setelah saya memuat jquery sangat bagus.
Ron
6

Membangun solusi Demircan Celebi; Saya ingin tab terbuka saat memodifikasi url dan buka tab tanpa harus memuat ulang halaman dari server.

<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>
Gavin
sumber
5

@flynfish + @Ztyx solusi yang saya gunakan untuk tab bersarang:

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

anak-anak harus memiliki class = "nested"

Artem Kashin
sumber
5

Saya datang dengan solusi yang menggunakan hash url atau localStorage tergantung pada ketersediaan yang terakhir dengan kode di bawah ini:

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

Saya sarankan Anda menggunakan kode yang disediakan oleh penulis Bootstrap pada pelacak masalah mereka di GitHub :

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

Anda dapat menemukan di tautan ke masalah ini informasi lebih lanjut tentang mengapa mereka tidak memilih untuk mendukungnya.

Alejandro García Iglesias
sumber
4

Mencoba beberapa cara yang dibahas di atas dan berakhir dengan mengikuti solusi yang berfungsi, cukup salin dan tempel di editor Anda untuk mencoba. Untuk menguji cukup ubah hash ke inbox, outbox, buat url dan tekan 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>

Semoga ini akan menghemat waktu Anda.

Abimanyu
sumber
3

Inilah yang saya lakukan, sangat sederhana, dan asalkan tautan tab Anda memiliki ID yang terkait dengannya, Anda bisa mendapatkan atribut href dan meneruskannya ke fungsi yang menampilkan konten tab:

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

Kemudian di url Anda, Anda dapat menambahkan hash sebagai sesuatu seperti: # tab_tab1, bagian 'tab_' dihapus dari hash itu sendiri sehingga ID tautan tab aktual di nav-tabs (tabid1) ditempatkan setelah ini, jadi Anda url akan terlihat seperti: www.mydomain.com/index.php#tab_tabid1.

Ini berfungsi sempurna untuk saya dan berharap ini membantu orang lain :-)

Derek Buntin
sumber
2

Ini solusi saya untuk menangani tab bersarang. Saya baru saja menambahkan fungsi untuk memeriksa apakah tab aktif memiliki tab induk untuk diaktifkan. Ini fungsinya:

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

Dan bisa disebut seperti ini (Berdasarkan solusi @ 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);
});

Solusi ini berfungsi cukup baik untuk saya saat ini. Semoga ini bisa bermanfaat untuk orang lain;)

Stefano Marra
sumber
2

Saya harus memodifikasi beberapa bit agar ini berfungsi untuk saya. Saya menggunakan Bootstrap 3 dan 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);
});
ruifn
sumber
Jawaban yang bagus, kecuali saya harus mengganti "!" awalan dengan "tab_". Kalau tidak bekerja dengan sempurna.
koziez
2

Cukup masukkan kode ini di halaman Anda:

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

Amin Gholibeigian
sumber
1

Saya baru saja mengalami masalah ini, tetapi perlu menangani beberapa level tab. Kode ini agak jelek (lihat komentar), tetapi melakukan tugasnya: https://gist.github.com/JensRantil/4721860 Semoga orang lain akan merasa berguna (dan merasa bebas untuk mengusulkan solusi yang lebih baik!).

Ztyx
sumber
1

Menggabungkan peices dari jawaban lain, berikut adalah solusi yang dapat membuka banyak level tab bersarang:

// 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');
}
cweston
sumber
hanya berfungsi pada 2 level sarang, level 3 menyebabkan masalah.
Nicholas Hamilton
Saya baru saja menguji ini terhadap tiga tingkat tab, dan tampaknya berfungsi untuk saya. Apakah Anda yakin ini bukan masalah dengan implementasi Anda? Apa masalah yang Anda alami?
cweston
Setiap tab di level 1 dan 2 berfungsi dengan baik, namun di level 3, saat menyegarkan halaman (atau mengirimkan formulir), ketika halaman dibuka kembali, fokus diberikan ke tab pertama di level 2.
Nicholas Hamilton
Jadi sudah berfungsi ok (ada kesalahan ketik kecil dalam kode saya), namun setelah koreksi kesalahan ketik, hanya dengan $('.nav-tabs li a').click( function(e) { history.pushState( null, null, $(this).attr('href') );});di javascript di atas kode Anda.
Nicholas Hamilton
1

Jika penting bagi siapa pun, kode berikut ini kecil dan berfungsi tanpa cacat, untuk mendapatkan nilai hash tunggal dari URL dan menunjukkan bahwa:

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

apa yang dilakukannya adalah mengambil id dan menjalankan event klik. Sederhana.

Sam
sumber
0

Saya membuat sth seperti ini untuk tautan dengan ajax #!#(mis / test.com #! # Test3) tetapi Anda dapat memodifikasinya apa pun yang Anda suka

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

Contoh dengan halaman sederhana di Github di sini

eudaimonia
sumber
0

Saya tahu utas ini sangat lama, tetapi saya akan meninggalkan di sini implementasi saya sendiri:

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

Perhatikan bahwa saya menggunakan nav-awalan kelas ke tautan nav.

Renan Coelho
sumber