Créer un menu « accordéon » avec jQuery
Vous avez aimé cet article ? Apportez votre petit « plus » ci-dessous !
Voici un superbe tutorial proposé par Thomas Dedericks de chez AlsaCreations pour vous permettre de créer un menu de type accordéon en JavaScript à l’aide de jQuery
Introduction
Le but de ce tutoriel est de transformer le menu HTML du chapitre suivant en un menu « accordéon ». Un menu « accordéon » est un menu déroulant un peu particulier, dont les sous-menus s’ouvrent au clic de souris (ou au focus).
Pour cela, on va bien sûr utiliser JavaScript, mais en se basant sur la bibliothèque jQuery. J’ai utilisé la version 1.2.1 de jQuery, la plus récente au moment d’écrire ces lignes.
Pour plus de renseignements sur le fonctionnement et les possibilités offertes par jQuery, je vous invite à consulter la documentation en ligne, très utile (mais uniquement en anglais).
Le code HTML : Structure (X)HTML
Voici le code de base du menu :
<ul class="navigation"> <li><a title="Aller à la page 1" href="#">Item 1</a></li> <li class="toggleSubMenu"><span>Item 2</span> <ul class="subMenu"> <li><a title="Aller à la page 2.1" href="#">Item 2.1</a></li> <li><a title="Aller à la page 2.2" href="#">Item 2.2</a></li> <li><a title="Aller à la page 2.3" href="#">Item 2.3</a></li> </ul> </li> <li class="toggleSubMenu"><span>Item 3</span> <ul class="subMenu"> <li><a title="Aller à la page 3.1" href="#">Item 3.1</a></li> <li><a title="Aller à la page 3.2" href="#">Item 3.2</a></li> </ul> </li> <li><a title="Aller à la page 4" href="#">Item 4</a></li> </ul> |
qu’il faudra bien sûr insérer dans une page HTML complète (par exemple, une page générée par Squelettor).
Remarquez la présence des éléments span
dans les éléments de liste qui contiennent des sous-menus, ainsi que les classes utilisées sur ces mêmes éléments et les sous-menus.
Images employées
Les images employées pour ce tutoriels sont celles-ci :
Vous pouvez bien évidemment employer vos propres images, voire ne pas en utiliser du tout et vous contenter des styles CSS.
Le code JavaScript : Intégrer jQuery
La première chose à faire pour pouvoir utiliser jQuery est bien évidemment d’appeler la librairie dans la page. Téléchargez jQuery sur le site officiel, et placez-le dans le répertoire (ou dans un sous-répertoire) où vous avez enregistré le fichier HTML.
Nous allons insérer l’appel au fichier jQuery dans la balise head
, comme décrit dans ce point de la FAQ :
<script src="jquery-1.2.1.js" type="text/javascript"><!--mce:0--></script> |
Dorénavant, on peut accéder aux méthodes de la bibliothèque jQuery dans tout le reste de la page.
Cacher les sous-menus
<script type="text/javascript"><!--mce:1--></script> |
On aurait évidemment pu cacher les sous-menus en appliquant la propriété CSS display: none
, mais cette façon de faire rend le menu inutilisable pour les utilisateurs qui ne disposent pas de JavaScript ou qui l’ont désactivé.
Transformer les span en liens
Il est possible de faire réagir les éléments de liste au clic pour faire apparaître les sous-menus, comme n’importe quel élément HTML. Le problème est que les éléments de liste ne captent pas le focus lorsque l’utilisateur navigue au clavier, contrairement aux liens.
Evidemment, on pourrait utiliser directement un lien, avec un attribut href
vide. Mais dans ce cas, on se retrouve avec un lien inutile si JavaScript est désactivé.
Pour obtenir un résultat aussi accessible et ergonomique que possible (pour un menu déroulant), j’ai choisi de générer des liens à l’aide de JavaScript. Ainsi, le code HTML reste propre et le menu devient utilisable au clavier.
<script type="text/javascript"><!--mce:2--></script> |
Gérer l’affichage des sous-menus
Il faut maintenant que les sous-menus se déroulent lorsque l’on clique sur les liens. On va utiliser un des effets graphique fournis par jQuery, via la fonction slideToggle
, qui fera apparaitre/disparaitre les sous-menus en augmentant/reduisant progressivement leur hauteur.
Il y a deux cas de figure qui peuvent se présenter lorsque l’utilisateur clique sur un lien :
- soit le sous-menu correspondant est ouvert, et on doit simplement le replier ;
- soit le sous-menu est fermé. Dans ce cas, il faut afficher le sous-menu correspondant et fermer les autres sous-menus.
Il n’est pas difficile de réaliser qu’en procédant de cette manière, il n’y aura jamais plus d’un seul sous-menu affiché, puisqu’à chaque fois qu’on en ouvre un, on referme les autres ! Combinée avec les effets de « slideUp » et « slideDown », cette méthode donnera l’effet « d’accordéon » recherché.
Voici le code modifié :
<script type="text/javascript"><!--mce:3--></script> |
Plusieurs points intéressants à creuser ici, et notamment :
- l’utilisation du filtre
:visible
; - la fonction next() qui permet de rechercher un élément voisin, i.e. ayant le même parent ;
-
Le sélecteur CSS de descendance directe
>
, qui permet ici de ne pas sélectionner les liens contenus dans les sous-menus.
Et voilà, le menu est d’ores et déjà fonctionnel ! Mais il est encore largement perfectible …
Les styles CSS
Pour commencer, nous allons utiliser les styles CSS pour rendre le menu un peu plus sexy. Voici les styles utilisés dans l’exemple :
.navigation { margin: 0; padding: 0; list-style: none; background: #000; color: #fff; width: 200px; font: 1.2em "Trebuchet MS", sans-serif; } .navigation a, .navigation span { display: block; padding: 4px 10px; color: #fff; text-decoration: none; background: #000 url(menu-item.png) left bottom no-repeat; } .navigation .toggleSubMenu a, .navigation .toggleSubMenu span { background-image: url(menu-item-deroule.png); } .navigation .open a, .navigation .open span { background-image: url(menu-item-enroule.png); } .navigation a:hover, .navigation a:focus, .navigation a:active { text-decoration: underline; } .navigation .subMenu { font-size: .8em; background: #ccc url(subMenu.png) 0 0 repeat-x; font-size: .9em; margin: 0; padding: 0; border-bottom: 1px solid #666; } .navigation ul.subMenu a { background: none; padding: 3px 20px; } |
Hop, c’est déjà nettement plus agréable à regarder, pas vrai ? Évidemment, il reste quelques bugs à corriger sous IE6 et consorts, mais ce n’est pas l’objet de ce tutoriel … débrouillez-vous
Et si vous voulez savoir à quoi sert la classe "open"
, continuez à lire !
Améliorer l’ergonomie : Marquer les éléments « déclencheurs »
Pour améliorer l’ergonomie du menu, on va faire en sorte de distinguer les liens qui déclenchent le déroulement d’un sous-menu des autres. Et dans la foulée, on va aussi distinguer ceux qui permettent de cacher un sous-menu.
Pour cela, il nous suffit d’ajouter une classe aux éléments de liste dans lesquels il y a un sous-menu ouvert. On pourra en effet modifier l’apparence de cet élément à l’aide des styles. Les autres éléments contenant un sous-menu sont déjà connus, ils portent tous la classe toggleSubMenu
!
Donc, en résumé, lorsqu’on ouvre le sous-menu, il faut ajouter une classe (par exemple « open »), et lorsqu’on le referme, il faut la supprimer. Il faudra aussi supprimer cette classe si elle existe pour un autre sous-menu.
jQuery possède deux méthodes, addClass()
et removeClass()
, qui vont faire la majorité du travail à notre place :
<script type="text/javascript"><!--mce:4--></script> |
Il suffit maintenant de styler li.open
et li.toggleSubMenu
différemment grâce aux CSS.
Garder un sous-menu ouvert
Lorsque le visiteur clique sur un des « vrais » liens du menu, il est normalement envoyé sur une autre page. Résultat, la page est rechargée, et le sous-menu dans lequel l’utilisateur naviguait n’apparait plus, il a été fermé.
Il est possible de le garder ouvert après un changement de page, mais on va avoir besoin d’intervenir directement sur le code HTML.
Si votre site est statique, il suffit d’ajouter à la main une classe (par exemple « open_at_load ») sur le sous-menu que vous voulez garder ouvert (en fonction de la page). Pour les sites dynamiques, il est aussi possible de générer cette classe, en fonction d’une variable $_GET['page']
ou autre.
Dès lors, il suffit de dire au script de fermer tous les sous-menus au chargement, sauf celui qui porte la classe « open_at_load » :
<script type="text/javascript"><!--mce:5--></script> |
Conclusion
Le menu n’est pas vraiment terminé. Il reste quelques améliorations faciles à apporter, notamment en utilisant la méthode des portes coulissantes pour les effets de survol CSS au lieu d’images séparées (ou en préchargeant les images via JavaScript). Mais vous trouverez les techniques nécessaires dans d’autre tutoriaux, et pas très loin d’ici.
Récapitulons : nous avons réalisé un menu accordéon qui fonctionne avec les principaux navigateurs du marché, qui reste accessible et logique si JavaScript est désactivé, et utilisable au clavier. Le tout avec, si je compte bien, une vingtaine de lignes de code JavaScript. Pas mal !
La bibliothèque jQuery offre bien d’autres possibilités. Je vous invite à explorer un peu son fonctionnement, en changeant l’effet utilisé pour afficher les sous-menus, la vitesse, etc. Amusez-vous …
Le principal inconvénient des bibliothèques JavaScript est (était ?) leur poids souvent excessif. À vous de voir si les 27 ko de jQuery valent la peine ou pas …
Remerciement
Un grand merci à Thomas Dedericks qui a rédigé ce superbe tutoriel
Mots-clefs : alsacreations, CSS, javascript, jquery, menu accordeon
Rétrolien depuis votre site.
Commentaires (12)
Sophie
| #
Merci pour ce tutoriel mais il y a qqchose qui me chiffone. Je ne comprends pas pourquoi changer la balise span pour en faire un lien qui ne pointe sur rien.
Ou est l’intéret?
Si on supprime cette partie ci du code:
Et que on remplace celle-ci:
par
Ca fonctionne aussi bien alors pourquoi transformer ce span en balise href?
Répondre
aDy
| #
Coucou Sophie !
En fait la balise span est un simple conteneur (comparable à la balise DIV) qui ici, est moins adapté pour cliquer et afficher donc le sous-menu.
Tu remarqueras que ici le lien possède un attribut « title » qui n’est pas compatible avec la balise span.
Enfin je ne suis pas certain que l’attribut rel= »nofollow » soit indispensable ici vu que le lien ne pointe nulle part.
Hésite pas si tu as d’autres questions
Répondre
Ronan
| #
Bonjour, et merci pour le partage de tuto ! Je me suis servi de ce tuto pour réaliser un menu. Jusque là tout va bien tout fonctionne… mais, car oui il y a un mais, je souhaiterai faire des sous-sous-menu, malheuresement ça ne fonctionne pas, ou alors je m’y prends mal, aurais-tu quelques minutes à m’accorder pour m’aider ?
Merci par avance.
Cordialement,
Ronan.
Répondre
SKIBINSKI freddy
| #
Bonjour, et merci pour cet excellent tuto
J’ai juste un problème pour la classe « open_at_load ». Je ne sais pas où la placer dans le code HTML dans la page appelée pour que le sous-menu reste ouvert
merci de m’nvoyer le code HTML pour la classe « open_at_load ».
Cdlt
freddy.
Répondre
Ivy
| #
Bonjour,
J’ai exactement le même soucis que Freddy en ce qui concerne le open_at_load. Pourriez vous me donner le code HTML pour cette classe open_at_load
Merci
Ivy
Répondre
djcoyotte
| #
Pour rajouter une class sur un menu static (c’est à dire qui est present sur toutes tes pages html) rien de plus simple :
voici un exemple de menu :
Si tu veut que le sous menu de la RUBRIQUE 1 reste ouvert tu rajoute la class open_at_load au SUBMENU:
si tu veut que se soit pour la rubique deux meme principe en prenant soin d’effacer le open_at_load sur la rubrique 1 sinon tes deux menu resteront ouvert…:
voila j’espère que j’ai pu aider certain d’entre vous…
Par contre moi j’ai un autre souci puisque mon menu est gérer dynamiquement. c’est à dire que j’ai une page index.php avec mon menu et d’autreS pageS injecter sur mon « index » par un include… mon souci c’est de créer une variable qui se sur chacune de mes pages (ex: ) et de la recuperer sur mon menu (ex: ) mais cela ne fonctionne pas…
Quelqu’un peut-il m’éclairer?
Merci d’avance !
Répondre
djcoyotte
| #
mince toute mes excuses j’ai oublier de mettre en code… quelqu’un peut-il modifier ca?
Répondre
aDy
| #
C’est fait !
Merci de ta contribution
Répondre
Créer un menu « accordéon » avec jQuery | Creation site Intenet et logiciel, web agency Lyon – Blog AVANIM
| #
[…] : /06/12/2008/creer-un-menu-accordeon-avec-jquery/ Cette entrée a été publiée dans AJAX & jQuery, avec comme mot(s)-clef(s) accordeon ajax, […]
Répondre
rais
| #
merci infiniment pour votre aide c est genial ca me plais je veux l appliquer dans mon site que je viens de creer : a bien tot.
Répondre
Adrien
| #
Avec plaisir rais !
Répondre
Rakoto
| #
Bonjour,
quelqu’un pourrait me montrer comment remplacer le texte Page 2 par exemple par un image?
Répondre