Twitter Bootstrap-onglets-URL ne change pas
J'utilise Twitter Bootstrap et ses "onglets".
J'ai le code suivant:
<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>
Les onglets fonctionnent correctement, mais la dans l'URL n'est pas ajouté le #ajouter #modifier, #supprimer.
Lorsque je supprime data-toggle
l'URL change, mais les onglets ne fonctionnent pas.
Des solutions pour cela?
14 réponses
Essayez ce code. Il ajoute l'onglet href à l'url + ouvre l'onglet en fonction du hachage lors du chargement de la page:
$(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);
});
});
Il y a trois composants nécessaires pour une solution complète:
- affiche l'onglet correct lorsque la page est chargée s'il y a un hachage dans L'URL.
- Modification du hachage dans L'URL lorsque l'onglet est modifié.
- changez l'onglet lorsque le hachage change dans L'URL (boutons Précédent / Suivant), et assurez-vous que le premier onglet est correctement cyclé.
Je ne pense pas que les commentaires ici, ni la réponse acceptée, gèrent tous ces scénarios.
Comme il y a tout à fait un peu impliqué, je pense que c'est le plus propre comme un petit plugin jQuery: https://github.com/aidanlister/jquery-stickytabs
, Vous pouvez appeler le plugin comme ceci:
$('.nav-tabs').stickyTabs();
J'ai fait un billet de blog pour cela, http://aidanlister.com/2014/03/persisting-the-tab-state-in-bootstrap/
En utilisant data-toggle="tab"
demande à le plugin de gérer les onglets, qui tout en le faisant appelle preventDefault
sur l'événement (code sur github ).
Vous pouvez utiliser votre propre activation d'onglet, et laisser passer l'événement:
$('.nav-tabs a').click(function (e) {
// No e.preventDefault() here
$(this).tab('show');
});
Et vous devez supprimer l'attribut data-toggle="tab"
Vérifier , le doc si vous avez des doutes.
Comme vos éléments d'ancrage modifient déjà le hachage de l'url, l'écoute de l'événement onhashchange est une autre bonne option. Comme @flori l'a déjà mentionné, cette méthode fonctionne bien avec le bouton de retour du navigateur.
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");
Enfin, le déclenchement de l'événement juste après avoir défini l'écouteur aidera également à afficher l'onglet de droite lors du chargement de la page.
Ma solution à votre problème:
Ajoutez D'abord un nouvel attribut data-value
à chaque lien a
, comme ceci:
<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>
Deuxièmement, changez les ID des onglets, par exemple de add
à tab-add
, Mettez également à jour les hrefs pour inclure le préfixe 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>
Et enfin le code 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>
Voici jsFiddle - mais cela ne fonctionne pas à cause de l'iframe utilisé par jsFiddle, mais vous pouvez lire la source de ma solution.
Il existe également un moyen simple de réagir aux changements de hachage (par exemple, le bouton Retour). Ajoutez simplement un écouteur d'événement hashchange à la solution 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);
});
Même problème avec CakePHP avec Bootstrap 3 onglets, plus quand j'envoie avec URL externe et ancre, il saute à la section perdre mon menu, après examen de nombreuses solutions ont fait cela...
Grâce à: 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
Pour ceux qui utilisent Ruby on Rails ou tout autre script côté serveur, vous voudrez utiliser l'option anchor
sur les chemins. C'est parce qu'une fois que la page se charge, elle n'a pas le hachage D'URL disponible. Vous voudrez fournir l'onglet correct via votre lien ou la soumission de formulaire.
<%= form_for @foo, url: foo_path(@foo, anchor: dom_id(foo)) do |f| %>
# Or
<%= link_to 'Foo', foo_path(@foo, anchor: dom_id(foo)) %>
Si vous utilisez un préfixe pour empêcher la fenêtre de sauter à l'id:
<%= form_for @foo, url: foo_path(@foo, anchor: "bar_#{dom_id(foo)}") do |f| %>
Alors vous 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
Ou 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);
});
Cela devrait fonctionner dans Bootstrap 3.
Merci à @ tomaszbak pour la solution originale cependant puisque mes modifications ont été rejetées et que je ne peux pas commenter son message, je vais laisser ma version légèrement améliorée et plus lisible ici.
Il fait fondamentalement la même chose mais si résout le problème de compatibilité entre les navigateurs que j'ai eu avec le sien.
$(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
});
});
Voici une option utilisant history.pushState
afin que vous puissiez utiliser l'historique de votre navigateur pour revenir à un onglet précédent
$(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');
}
});
});
J'utilise Bootstrap 3.3.* et aucune de la solution ci-dessus ne m'a aidé, même marqué comme réponse. Je viens d'Ajouter ci-dessous script et travaillé.
$(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'));
});
});
J'espère que cela vous aidera.
Aucun de ce qui précède n'a fonctionné pour moi, alors voici comment j'ai fait fonctionner le mien:
- ajouter
class="tab-link"
à tous les liens ayant besoin de cette fonctionnalité - Ajoutez le code suivant à votre javascript:
window.addEventListener ( 'popstate', function( event ) { tab_change(); } ); function tab_change() { var hash = window.location.hash; hash && $( 'ul.nav a[href="' + hash + '"]' ).tab( 'show' ); $( '.tab-link' ).click ( function( 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' ); } ); }
Cela corrige également un onglet extrêmement obscur un href ne tirant pas lors de l'utilisation de jquery et 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>