Un menu à onglets très simple à réaliser avec jQuery

20
Menu à onglets avec jQuery.

Menu à onglets avec jQuery.

La navigation par onglets vous permet d’afficher séparément les multiples sections d’un document et ce, sans changer de page. Cette technique peut être avantageuse si vous êtes contraint à présenter une page Web très chargée.

Le code HTML

Pour l’exemple, nous choisirons un contenu simple : Un bloc (<div id="listSites">) avec deux hyperliens servira de menu. En-dessous deux autres blocs (logicielsLibres, sitesInformations) représenteront de courtes listes de mes sites Web préférés. Le but de l’exercice sera de faire apparaître une liste ou l’autre en cliquant sur le lien correspondant. Mais voyons d’abord à quoi ressemble cette page HTML sans le script:

<h2>Mes sites Web préférés</h2>

<div id="listSites">
    <a href="#logicielsLibres">Sites sur les logiciels libres</a><br/>
    <a href="#sitesInformations">Sites d'information</a>
</div>

<div class="tabContent" id="logicielsLibres">
    <strong>Framasoft.net, Planet-libre.org ...</strong>
</div>

<div class="tabContent" id="sitesInformations">
    <strong>Smashingmagazine.com, Blog.kryzalid.net ...</strong>
</div>

Les items du menu utilisent une navigation par ancres, lesquels pointent vers les blocs logicielsLibres et sitesInformations. Ainsi, le menu sera utilisable par les utilisateurs qui n’ont pas accès à JavaScript, car il est important de rendre le contenu d’un site Web fonctionnel et accessible pour tous, sans autre technologie que le HTML.

Le code javascript

D’abord intégrer jQuery

jQuery est une bibliothèque de scripts qui a pour but de simplifier l’écriture et l’utilisation du JavaScript. Télécharger jQuery sur le site officiel, et le placer dans le répertoire (ou dans un sous-répertoire) à la racine de vos pages HTML. Puis appeler jQuery dans le <head></head> de la page Web.

<script type="text/javascript" src="js/jquery-1.3.2.js"></script>

Juste en-dessous, ajouter la balise <script></script> suivante :

<script type="text/javascript">

$(document).ready(function(){
/*Ici le script*/
});

</script>

Important ! Notez qu’en JavaScript tout ce qui se trouve entre /* et */ est considéré comme un commentaire et sera alors ignoré par le navigateur.

Tout ce qui se retrouve entre $(document).ready(function(){}); sera exécuté aussitôt que le document sera chargé dans le navigateur.

Cacher les blocs de contenu

D’abord, pour faire apparaître quelque chose, il faut le faire disparaître :) . Dans notre cas, nous voulons faire disparaître les blocs (div) qui ont la class tabContent. Mais en général, les gens n’aiment pas arriver sur une page qui n’a aucun contenu. Nous allons donc cacher ici tous les blocs sauf le premier :

<script type="text/javascript">
$(document).ready(function(){

    $(".tabContent:not(:first)").hide(); 
$(".tabContent").not(":first").hide();
/*Cacher les blocs avec la class tabContent sauf le premier de la liste*/ }); </script>

Afficher le contenu en cliquant sur les éléments du menu

Vous l’avez déjà sans doute remarqué dans le code HTML : chaque lien a un attribut href qui correspond à peu près à l’attribut id d’un bloc tabContent.

  • <a href="#logicielsLibres">Sites sur les logiciels libres</a> → pointe vers → <div class="tabContent" id="logicielsLibres">...</div>
  • <a href="#sitesInformations">Sites d'information</a> → pointe vers → <div class="tabContent" id="sitesInformations">...</div>

Le dièse (#) dans l’attribut href indique au navigateur que ce lien fait référence à une ancre (cible) dans un document. Dans ce cas-ci, le lien href="#logicielsLibres" à pour destination le bloc id="logicielsLibres".

Pour les besoins de notre script, nous allons utiliser cette relation entre lien et cible. Nous pouvons formuler le script ainsi : « Quand je clique sur un lien (<a>) qui se trouve dans le bloc listSites, afficher le bloc qui a un id qui est semblable au href du lien sur lequel je suis en train de cliquer« . :P

Notre script ressemblera à ceci :

<script type="text/javascript">
$(document).ready(function(){

    $(".tabContent:not(:first)").hide();
    $(".tabContent").not(":first").hide();

    $("#listSites a").click(function() { /*En cliquant sur un lien du bloc listSites, on déclenche la fonction suivante */
        var idTab = $(this).attr("href"); /*La variable idTab correspond à la valeur de l'attribut href du lien actif*/
        $(".tabContent").hide(); /*Cache tous les blocs tabContent actuellement visible*/
        $("div[id='" + idTab + "']").fadeIn(); /*Affiche le bloc dont le id correspond à la valeur courante de la variable idTab*/
        return false; /*Nous disons au navigateur de ne pas suivre les liens*/
    }); /*La fonction de l'événement .click() se termine ici*/

});
</script>

Nous avons presque terminé

À ce stade, nous avons presque terminé. Mais si vous testez, vous verrez que le script n’est pas encore fonctionnel ! C’est que les valeurs des attributs href ne sont pas exactement semblables à ceux des attributs id correspondant et ce, à cause des dièses (#). Nous pourrions en ajouter aux id directement dans le HTML, mais on obtiendrait une erreur de syntaxe, et notre menu serait inefficace pour les utilisateurs qui n’ont pas JavaScript. Nous allons donc le faire simplement en utilisant encore une fois JavaScript :

<script type="text/javascript">
$(document).ready(function(){

    $(".tabContent").each(function(i){ /*Pour chaque élément ayant la class tabContent, exécuter la fonction suivante*/
        this.id = "#" + this.id; /*Le id est maintenant le id + un dièse devant*/
    }); /*La fonction du sélecteur .each() se termine ici*/

    $(".tabContent:not(:first)").hide();
    $(".tabContent").not(":first").hide();

    $("#listSites a").click(function() {
        var idTab = $(this).attr("href");
        $(".tabContent").hide();
        $("div[id='" + idTab + "']").fadeIn();
        return false;
    });   

});
</script>

Voilà, maintenant notre menu à onglets devrait fonctionner à merveille ! Simple n’est-ce pas ?

Le code JavaScript complet

<script type="text/javascript">
$(document).ready(function(){

    $(".tabContent").each(function(i){
        this.id = "#" + this.id;
    });

    $(".tabContent:not(:first)").hide();
    $(".tabContent").not(":first").hide();

    $("#listSites a").click(function() {
        var idTab = $(this).attr("href");
        $(".tabContent").hide();
        $("div[id='" + idTab + "']").fadeIn();
        return false;
    });   

});
</script>

Cet article a été publié le Jeudi 7 mai 2009 à 4:48

Vous pouvez en suivre les commentaires par le biais du flux RSS 2.0.

Vous pouvez laisser un commentaire ou rétrolier de votre site Web.

20 commentaires

  1. Pierre,

    Bonjour,
    merci pour ce billet très bien expliqué pour des débutants comme moi en jquery. Petite question complémentaire : Est ce possible de pointer un lien depuis une autre page vers l’onglet 3 par exemple, du type mapage.php#onglet3 ?

    Merci.

    • Bonjour Pierre, merci de votre commentaire :)

      Désolé pour le délais de cette réponse, vendredi dernier a été passablement occupé … Maintenant pour répondre à votre question, oui c’est possible d’accéder à un onglet en particulier à partir d’une page externe.

      Voici rapidement comment procéder :

      Dans la page où se trouve le script, juste à la suite de votre balise ‹html›, ajouter
      ‹?php $appelOnglet=$_GET["onglet"] ; ?›

      Ensuite juste avant la fin de la fonction $(document).ready(function(){}); insérer ce script :

      var appelOnglet = "‹?=$appelOnglet?›" ;
      if(appelOnglet !="") {

      $(".clientBox").hide();
      $("div[id='#" + appelOnglet + "']").fadeIn();

      }

      Donc votre script devrait maintenant ressembler à ça :

      ‹script type= »text/javascript »›
      // < ![CDATA[
      $(document).ready(function(){

      $(".clientBox").each(function(i){
      this.id = "#" + this.id;
      });

      $(".clientBox").not(":first").hide();

      $("#listClients a").click(function() {
      var idClient = $(this).attr("href");
      $(".clientBox").hide();
      $("div[id='" + idClient + "']").fadeIn();

      return false;
      });

      var appelOnglet = "‹?=$appelOnglet?›" ;
      if(appelOnglet !="") {

      $(".clientBox").hide();
      $("div[id='#" + appelOnglet + "']").fadeIn();

      }

      });
      // ]]>
      ‹/script›

      Puis vos liens prendront cette forme :
      ‹a href="tabs-nav-exemple-complet.php?onglet=leIdDuDiv"›Cliquer ici‹/a›

      Voilà, j’espère avoir répondu à votre question … si vous avez besoin de précisions, n’hésiter pas !

      Bonne semaine !

  2. Très bon tuto Hugo. Est-ce que l’historique de navigation fonctionne avec ce genre de menu?

    • Salut Benoît, merci pour ton commentaire…

      Non dans ce cas l’historique de navigation ne fonctionnera pas.

      Bonne journée et à bientôt !

  3. karty,

    Bonjour,

    est-il possible de rajouter un morceau de code pour changer la couleur de l’onglet actif par exemple ?

    Merci a+

    • Bonjour Karty,

      oui ce que tu demandes est tout à fait possible, et grâce à jQuery, très simple à réaliser.

      Tout d’abord dans la feuille de style on va ajouter une classe qui sera le style de l’onglet actif. Moi je l’ai nommé current, mais tu peux lui donner un autre nom si celui-ci ne fait pas ton affaire. Puis je lui ai donné la valeur « background:yellow » question de ne pas trop rendre les choses compliquées.

      Bon une fois que le style est créé il ne reste que deux trois lignes de jQuery à ajouter. Premièrement, juste en dessous de la ligne $(‘div[id='" + idTab + "']‘).fadeIn(); tu écris $(this).addClass(‘current’); … Cette ligne va ajouter la classe current que nous avons créée précédemment dans notre feuille de style sur le bouton qui est actif.

      Comme cela le script fonctionne déjà, mais le style va demeurer sur les boutons, donc ils auront tous une couleur de fond jaune; Ce n’est pas vraiment ce que nous voulons… Nous aimerions plutôt avoir un seul bouton jaune à la fois.

      Pour faire cela en-dessous de la ligne $(‘.tabContent’).hide(); tu écris $(‘#listSites a’).removeClass(); … Alors ici nous indiquons au navigateur d’enlever d’abord toutes les classes de tous les onglets avant d’ajouter la classe current sur l’onglet qui est actif.

      Voilà, tu peux voir le résultat en consultant le premier exemple de ce billet.

      J’espère avoir bien répondu à ta question… Au revoir et bonne journée !

  4. karty,

    Merci Hugo !

  5. Bonjour,

    je voudrais savoir s’il était possible d’effectuer cet effet au survol de la souris et non au clique ?

    Merci

  6. dan95,

    J’ai longuement rechercher un menu à onglet en jquerry animé et ce billet est excellent à la fois pour sa simplicité et pour le détail de ces explications. Et ça marche! :)
    @Jérémie : je me permet de répondre, ça peut servir à d’autre personne, oui pour le survol de la souris, il faut gérer l’événement en CSS il faut ajouter
    a.current:hover {background:yellow;}

    • Bonjour dan95,

      merci pour ton commentaire et merci également d’avoir répondu à Jérémie.

      Bonne journée

  7. Bloubi,

    Salut!

    Merci pour ce petit tuto, court et efficace.
    Je suis en train de tenter de l’adapter à mon site et j’ai deux principales différences de comportement.
    Il ne repère l’élément ‘current’ au départ (le premier lien n’apparait pas avec un background jaune au chargement de la page).
    Et il me laisse les backgrounds jaunes après avoir cliqué sur un autre lien.

    Aurais-tu une idée d’où ça peut venir ?

    Merci d’avance!

  8. Bloubi,

    Oublie tout, je suis un boulet :)

    Merci !

    • Bonjour Bloubi,
      merci pour ton commentaire. Content de voir que tu as trouvé ce qui clochait dans ton code; Si tu as d’autres questions n’hésite pas à nous écrire. Bonne année 2010 !

  9. allow,

    Bonjour,
    Je suis a la recherche d’un menu fonctionnel et le votre me semble très bien.
    Je voudrai que sur une page html, avec un menu s’ouvrent des iframes.

    J’ai deux questions :
    la « version plus consistante avec un menu CSS. » va t’elle aussi fonctionner si le javascript n’est pas activé?

    Comment peut on faire pour que le clic sur le lien du menu ouvre un cadre flottant avec le site cible dedans?
    comme sur ce site :
    http://www.pierrebertet.net/projects/jquery_superbox/francais.html

  10. allow,

    Pour le site d’exemple, allez a la partie « mode iframe »

    « Mode iframe

    Générer une box contenant une iframe.
    Démonstration

    Iframe Superbox (dimensions par défaut)

    Iframe Superbox (dimensions définies) »

  11. Bloubi,

    Salut Hugo.

    Je viens de voir qu’avec la version 1.3.2 de javascript, le premier onglet ne s’affiche plus sur IE8 notamment.
    Aurais-tu une solution pour ça (à part reprendre la 1.2.6) ?

    Merci d’avance !

    • Bonjour Boulbi, merci de relater ce bogue.

      Oui j’ai déjà rencontrer ce problème auparavant. C’est la syntaxe de sélection qui semble avoir changée dans jQuery.

      Il suffit de remplacer :

      $(".clientBox:not(:first)").hide();

      Par cela :

      $(".clientBox").not(":first").hide();

      Voilà, j’espère avoir répondu à ta question.

      Bonne journée et merci de nous lire.

      • Bloubi,

        Parfait ! Merci beaucoup !

  12. Knot,

    Bonjours.
    J’ai suivi le tuto, puis j’ai suivi les exlications de votre réponse à Pierre, cependant :
    Si ma page est chargée pour la première fois, la variable $_GET['onglet'] n’existe pas, ce qui me cause une petite erreur puisqu’elle n’est pas initialisée. Mais si je met un (isset) pour tester si la variable existe, tout le script déconne (tous les onglets s’affichent sur la même page comme si le js ne fonctionnait pas). Pouvez vous m’aider ?

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>