web-dev-qa-db-fra.com

Twitter Bootstrap _ Onglets: Accédez à l'onglet spécifique dans Recharger une page ou un lien hypertexte

Je développe une page Web dans laquelle j'utilise le Bootstrap Framework de Twitter et leurs Bootstrap Tabs JS . Cela fonctionne très bien, à l’exception de quelques problèmes mineurs, dont l’un est que je ne sais pas comment aller directement à un onglet spécifique à partir d’un lien externe. Par exemple:

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

devrait aller à l'onglet Accueil et l'onglet Notes respectivement lorsque vous cliquez sur les liens d'une page externe

335
mraliks

Voici ma solution au problème, un peu tard peut-être. Mais cela pourrait peut-être aider les autres:

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

UPDATE

Pour Bootstrap 3, remplacez .on('shown', ...) par .on('shown.bs.tab', ....)


Ceci est basé sur @ dubbe answer et this SO accepte la réponse . Il gère le problème avec window.scrollTo(0,0) ne fonctionne pas correctement. Le problème est que lorsque vous remplacez le hachage de l'URL sur l'onglet affiché, le navigateur fait défiler jusqu'à ce hachage puisqu'il s'agit d'un élément de la page. Pour résoudre ce problème, ajoutez un préfixe afin que le hachage ne fasse pas référence à un élément de page réel.

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

Exemple d'utilisation

Si vous avez un onglet avec id = "mytab", vous devez mettre votre lien comme ceci:

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

vous pouvez déclencher un événement click sur le lien de l'onglet correspondant:

$(document).ready(function(){

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

});
50
Marian Theisen

Ceci est une implémentation améliorée de la solution de dubbe qui empêche le défilement.

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

Bien que la solution JavaScript fournie puisse fonctionner, j’ai opté pour une méthode légèrement différente, qui ne nécessite aucun JavaScript supplémentaire, mais qui nécessite une logique de votre part. Vous créez un lien avec un paramètre d'URL standard, tel que:

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

Ensuite, vous détectez simplement la valeur de activeTab pour écrire 'class = "active"' dans le <li> approprié

Pseudocode (implémente en conséquence dans votre langue). Remarque J'ai défini l'onglet 'accueil' comme actif par défaut si aucun paramètre n'est fourni dans cet exemple.

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

Pour Bootstrap 3:

$('.nav-tabs a[href="#' + tabID + '"]').tab('show');

https://jsfiddle.net/DTcHh/6638/

10
Razan Paul

Je ne suis pas un grand fan de if ... else; j'ai donc adopté une approche plus simple.

$(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. Choisissez un onglet par défaut (généralement le premier)
  2. Basculez vers l'onglet (si un tel élément est effectivement présent; laissez jQuery le gérer); Rien ne se passe si un mauvais hash est spécifié
  3. [Facultatif] Mettez à jour le hachage si un autre onglet est sélectionné manuellement

Ne traite pas du défilement vers le hachage demandé; mais devrait c'est?

9
visitsb

Cela fonctionne dans Bootstrap 3 et améliore les deux meilleures réponses de dubbe et flynfish en intégrant également la réponse de GarciaWebDev (qui autorise les paramètres d’URL après le hachage et provient directement de Bootstrap auteurs sur le traqueur de problèmes 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);
});
7
greggdavis

Ce code sélectionne le bon onglet en fonction du #hash et ajoute le droit #hash quand un onglet est cliqué. (cela utilise jquery)

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

ou en 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);
    });
});
6
Sucrenoir

S'appuyant sur la solution de Demircan Celebi; Je voulais que l'onglet s'ouvre lorsque vous modifiez l'URL et ouvrez l'onglet sans avoir à recharger la page à partir du serveur.

<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>
6
Gavin
$(function(){
  var hash = window.location.hash;
  hash && $('ul.nav a[href="' + hash + '"]').tab('show');
});

Ce code de http://github.com/Twitter/bootstrap/issues/2415#issuecomment-4450768 a parfaitement fonctionné pour moi.

5
tomaszbak

Merci de partager vos points de vue.

En lisant toutes les solutions. Je suis venu avec une solution qui utilise le hash url ou localStorage en fonction de la disponibilité de ce dernier avec le code ci-dessous:

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

@flynfish + solution @Ztyx que j'utilise pour les onglets imbriqués:

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

les enfants devraient avoir class = "imbriqué"

5
Artem Kashin

Je suggérerais que vous utilisiez le code fourni par les auteurs Bootstrap sur leur suivi des problèmes sur GitHub :

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

Vous pouvez trouver sur le lien vers le numéro plus d'informations sur les raisons pour lesquelles ils n'ont pas choisi de soutenir cela.

Essayé de deux manières discutées ci-dessus et aboutissez à la solution de travail suivante, il suffit de copier et coller dans votre éditeur pour essayer. Pour tester, changez simplement le hachage en boîte de réception, boîte d'envoi, composez l'URL et appuyez sur la touche Entrée.

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

J'espère que cela vous fera gagner du temps.

4
Abhimanyu

Voici ce que j'ai fait, très simple, et à condition que vos liens de tabulation soient associés à un identifiant, vous pouvez obtenir l'attribut href et le transmettre à la fonction qui affiche le contenu de l'onglet:

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

Ensuite, dans votre URL, vous pouvez ajouter le hachage sous la forme suivante: # tab_tab1, la partie 'tab_' est supprimée du hachage lui-même. L'URL ressemblerait à quelque chose comme: www.mondomaine.com/index.php#tab_tabid1.

Cela fonctionne parfaitement pour moi et j'espère que cela aidera quelqu'un d'autre :-)

3
Derek Buntin

Il suffit d'insérer ce code sur votre 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();
    window.location.hash = this.hash;
    $('html,body').scrollTop(scrollmem);
  });
});
2

J'ai dû modifier quelques bits pour que cela fonctionne pour moi. J'utilise Bootstrap 3 et 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);
});
2
ruifn

Ceci est ma solution pour gérer les onglets imbriqués. Je viens d'ajouter une fonction pour vérifier si l'onglet actif a un onglet parent à activer. C'est la fonction:

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

Et peut être appelé comme ceci (Basé sur la solution de @ 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);
});

Cette solution me convient pour le moment. J'espère que cela peut être utile pour quelqu'un d'autre;)

2
Stefano Marra

Je viens d'avoir ce problème, mais je devais gérer plusieurs niveaux de tabulation. Le code est plutôt moche (voir les commentaires), mais fait son travail: https://Gist.github.com/JensRantil/472186 J'espère que quelqu'un d'autre le trouvera utile (et n'hésitez pas à proposer de meilleures solutions !).

1
Ztyx

En combinant des éléments d'autres réponses, voici une solution qui peut ouvrir plusieurs niveaux d'onglets imbriqués:

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

Si cela importe à quiconque, le code suivant est petit et fonctionne parfaitement, pour obtenir une valeur de hachage unique à partir de l'URL et montrer que:

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

ce qu'il fait est qu'il récupère l'identifiant et déclenche l'événement click. Facile.

0
Samim

Je fais ça comme ça pour les liens avec ajax #!# (par exemple/test.com#!#test3) mais vous pouvez le modifier comme vous le souhaitez

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

Exemple avec une simple page sur Github ici

0
eudaimonia

Je sais que ce fil est très ancien, mais je vais laisser ici ma propre implémentation:

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

Notez que j'utilise un préfixe de classe nav- pour les liens de navigation.

0
Renan Coelho