Schede Bootstrap di Twitter: vai alla scheda specifica sulla pagina Ricarica o collegamento ipertestuale


358

Sto sviluppando una pagina Web in cui sto utilizzando Bootstrap Framework di Twitter e le sue schede Bootstrap JS . Funziona benissimo, tranne per alcuni problemi minori, uno dei quali è che non so come passare direttamente a una scheda specifica da un collegamento esterno. Per esempio:

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

dovrebbe andare rispettivamente alla scheda Home e alla scheda Note quando si fa clic sui collegamenti da una pagina esterna


49
vorrei che questo fosse incorporato!
Damon,

5
Questa domanda è stata sollevata anche qui: github.com/twitter/bootstrap/issues/2415 (e ha un paio di soluzioni lì).
Ztyx,


1
Il link aggiornato al problema bootstrap è github.com/twbs/bootstrap/issues/2415
bmihelac,

3
Plugin che risolve questo problema: github.com/timabell/jquery.stickytabs
Tim Abell

Risposte:


603

Ecco la mia soluzione al problema, forse un po 'in ritardo. Ma potrebbe forse aiutare gli altri:

// 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
Aggiungerei un'altra riga window.scrollTo(0, 0);in più per assicurarmi che la finestra scorra sempre verso l'alto
Trung Lê

1
$ ('. nav-tabs a [href * = #' + url.split ('#') [1] + ']'). tab ('show'); // Con un * è più sicuro poiché altrimenti corrisponde solo al primo # ...
mattangriffel

1
Online che ha funzionato per me: window.location.hash && $ ('li a [href = "' + window.location.hash + '"]'). Tab ('show'). Trigger ("click");
Decano Meehan,

10
Ecco una demo per Bootstrap 3: bootply.com/render/VQqzOawoYc#tab2 e il codice sorgente
Zim,

2
Dopo jquery aggiornamento a 1.11 da 1.09 ottengo questo errore: Syntax error, unrecognized expression: .nav-tabs a[href=#tab-2]. Risolto usando stackoverflow.com/questions/12131273/…
Pietro Z.

213

AGGIORNARE

Per Bootstrap 3, passare .on('shown', ...)a.on('shown.bs.tab', ....)


Questo si basa sulla risposta @dubbe e su questa risposta SO accettata . Gestisce il problema con il window.scrollTo(0,0)malfunzionamento. Il problema è che quando si sostituisce l'hash dell'URL nella scheda mostrata, il browser scorrerà a quell'hash poiché è un elemento nella pagina. Per ovviare a questo, aggiungi un prefisso in modo che l'hash non faccia riferimento a un elemento di pagina effettivo

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

Esempio di utilizzo

Se hai un riquadro con id = "mytab" devi inserire il tuo link in questo modo:

<a href="yoursite.com/#tab_mytab">Go to Specific Tab </a>

1
Ci sarebbe un modo semplice per fare riferimento ai segnalibri che si trovano in una scheda specifica? Ho cinque schede sulla mia pagina e sotto quelle ho un numero di segnalibri. Quello che vorrei è rendere questi segnalibri collegabili dall'esterno della scheda.
nize,

@nize se crei un jsfiddle con quello che stai cercando di fare, proverò a dare un'occhiata.
flynfish

1
Ecco una demo di Bootlpy per Bootstrap 3: bootply.com/render/VQqzOawoYc#tab2 e il codice sorgente
Zim

Nell'esempio sopra mancano le doppie virgolette sull'href. la linea 5 dovrebbe essere:$('.nav-tabs a[href="'+hash.replace(prefix,"")+'"]').tab('show');
Ponyboy,

Funziona per me, tranne per il fatto che ho dovuto rimuovere l'ultima barra (prima del #) in "yoursite.com/anotherpage/#tab_mytab", altrimenti si è rovinato il caricamento della pagina.
Alexander,

52

potresti attivare un clickevento sul collegamento della scheda corrispondente:

$(document).ready(function(){

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

});

Grazie per il consiglio! Questo ha funzionato alla grande con un piccolo problema. L'aggiornamento della pagina non lo porterebbe alla scheda corretta. Colpire Ctrl + F5 sarebbe. Ho modificato il codice nel modo seguente: `$ (document) .ready (function () {function getUrlVars () {var vars = {}; var parts = window.location.href.replace (/ [? &] + ([ ^ = &] +) = ([^ &] *) / gi, function (m, key, value) {vars [key] = value;}); return vars;} var action = getUrlVars () ["action" ]; if (action! = "") {$ ('a [href = "#' + action + '"]'). click ()};}); `
mraliks il

44

Questa è una migliore implementazione della soluzione di dubbe che impedisce lo scorrimento.

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

Mentre la soluzione JavaScript fornita può funzionare, sono andato in un modo leggermente diverso che non richiede JavaScript aggiuntivo, ma richiede logica nella tua vista. Si crea un collegamento con un parametro URL standard, come:

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

Quindi rilevi semplicemente il valore di activeTab per scrivere 'class = "active"' nell'appropriato <li>

Pseudocodice (implementare di conseguenza nella tua lingua). Nota Ho impostato la scheda 'home' come impostazione predefinita attiva se nessun parametro fornito in questo esempio.

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

Preferisco la tua soluzione alla soluzione JS a causa di una semplice ragione è che JS location.hash salta all'ID che causa la posizione del cursore su e giù.
Trung Lê,

Preferisco questa soluzione. In effetti, ho creato nuove rotte per le schede e la vista rigenerata impostando la classe attiva di conseguenza. Questo evita mal di testa di ridimensionamento della pagina, hash url e scorrimento della pagina tutti insieme.
Vijay Meena,

10

Non sono un grande fan di if ... else; quindi ho adottato un approccio più semplice.

$(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. Scegli una scheda predefinita (di solito la prima)
  2. Passa alla scheda (se un tale elemento è effettivamente presente; lascia che jQuery lo gestisca); Non succede nulla se viene specificato un hash sbagliato
  3. [Facoltativo] Aggiorna l'hash se viene scelta manualmente un'altra scheda

Non indirizza lo scorrimento all'hash richiesto; ma dovrebbe ?



8

Funziona in Bootstrap 3 e migliora le 2 risposte principali di dubbe e flynfish integrando anche la risposta di GarciaWebDev (che consente i parametri url dopo l'hash ed è direttamente dagli autori Bootstrap sul tracker del problema di 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);
});

1
questo non funziona in Bootstrap 3, 'shown'dovrebbe essere 'shown.bs.tab'per i documenti: getbootstrap.com/javascript/#tabs-events . Sono sconcertato sul perché, ma quando ho provato a modificare il tuo post è stato rifiutato ...
YPCrumble

6

Questo codice seleziona la scheda giusta a seconda di #hash e aggiunge la #hash giusta quando si fa clic su una scheda. (questo utilizza jquery)

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

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

assicurati di inserirlo dopo aver caricato jquery. Lo stavo mettendo nel mezzo di una pagina (era un posto facile per inserirlo per il test) e non ha funzionato. Metterlo dopo aver caricato jquery funziona alla grande.
Ron,

6

Basandosi sulla soluzione di Demircan Celebi; Volevo che la scheda si aprisse durante la modifica dell'URL e della scheda aperta senza dover ricaricare la pagina dal 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>


5

Soluzione @flynfish + @Ztyx che utilizzo per le schede nidificate:

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

i bambini dovrebbero avere class = "nidificato"


5

Ho trovato una soluzione che utilizza l'hash dell'URL o localStorage a seconda della disponibilità di quest'ultimo con il codice seguente:

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

Suggerirei di utilizzare il codice fornito dagli autori Bootstrap sul loro tracker dei problemi su GitHub :

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

Puoi trovare sul link al problema maggiori informazioni sul perché non hanno scelto di supportarlo.


4

Ho provato un paio di modi discussi sopra e alla fine con la seguente soluzione funzionante, basta copiare e incollare nel tuo editor per provare. Per testare basta cambiare l'hash in Posta in arrivo, Posta in uscita, comporre in url e premere il tasto Invio.

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

Spero che questo ti farà risparmiare tempo.


3

Ecco cosa ho fatto, davvero semplice, e purché i collegamenti alle tue schede abbiano un ID associato a loro puoi ottenere l'attributo href e passarlo alla funzione che mostra il contenuto della scheda:

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

Quindi nel tuo URL puoi aggiungere l'hash come qualcosa di simile: # tab_tab1, la parte 'tab_' viene rimossa dall'hash stesso in modo che l'ID del collegamento alla scheda reale nelle nav-tabs (tabid1) sia posizionato dopo questo, quindi il tuo url sarebbe simile a: www.mydomain.com/index.php#tab_tabid1.

Questo funziona perfettamente per me e spero che aiuti qualcun altro :-)


2

Questa è la mia soluzione per gestire le schede nidificate. Ho appena aggiunto una funzione per verificare se la scheda attiva ha una scheda padre da attivare. Questa è la funzione:

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

E può essere chiamato in questo modo (basato sulla soluzione di @ 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);
});

Questa soluzione funziona abbastanza bene per me al momento. Spero che questo possa essere utile per qualcun altro;)


2

Ho dovuto modificare alcuni bit affinché questo funzionasse per me. Sto usando Bootstrap 3 e 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);
});

Ottima risposta, tranne che ho dovuto sostituire il "!" prefisso con "tab_". Altrimenti ha funzionato perfettamente.
Koziez,

2

Basta inserire questo codice sulla tua pagina:

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

Ho appena avuto questo problema, ma dovevo gestire più livelli di tabulazione. Il codice è piuttosto brutto (vedi commenti), ma fa il suo lavoro: https://gist.github.com/JensRantil/4721860 Eventualmente qualcun altro lo troverà utile (e sentiti libero di proporre soluzioni migliori!).


1

Combinando peices da altre risposte, ecco una soluzione che può aprire molti livelli di schede nidificate:

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

funziona solo con 2 livelli di annidamento, il 3o livello causa problemi.
Nicholas Hamilton,

Ho appena provato questo su tre livelli di schede e sembra funzionare per me. Sei sicuro che questo non sia un problema con la tua implementazione? Quale "problema" stai riscontrando?
cweston,

Qualsiasi scheda di 1 ° livello e 2 ° livello funziona bene, tuttavia, nel 3 ° livello, quando si aggiorna la pagina (o si invia il modulo), quando la pagina si riapre, viene focalizzata sulla prima scheda del 2 ° livello.
Nicholas Hamilton,

Quindi ha funzionato bene (c'era un piccolo errore di battitura nel mio codice), tuttavia dopo la correzione di battitura, solo con $('.nav-tabs li a').click( function(e) { history.pushState( null, null, $(this).attr('href') );});il javascript sopra il codice.
Nicholas Hamilton,

1

Se è importante per qualcuno, il seguente codice è piccolo e funziona perfettamente, per ottenere un singolo valore di hash dall'URL e mostrare che:

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

ciò che fa è recuperare l'id e generare l'evento click. Semplice.


0

Faccio sth in questo modo per i collegamenti con ajax #!#(ad esempio / test.com #! # Test3) ma puoi modificarlo come preferisci

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

Esempio con una pagina semplice su Github qui


0

So che questo thread è molto vecchio, ma lascio qui la mia implementazione:

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

Nota che sto usando un nav-prefisso di classe per i collegamenti nav.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.