jan 23
Réaliser un panel à onglet simple avec Mootools
Objectifs
Je souhaitais réaliser un système de panel à onglet (ou tab panel in english) pour un site sur lequel je travaille. Le but est d’avoir peu de code, que ce soit facilement utilisable et implémentable mais également compatible avec la majorité des navigateurs. Sachant que je bosse avec le framework javascript Mootools, je vais l’utiliser pour me faciliter tout ça. Je souhaite également pouvoir mettre sur la même page plusieurs panels à onglets. Par contre, je tiens à ce que ça reste très simple, donc pas d’animation inutiles ou de fonctionnalités de-la-mort-qui-tue-mais-qui-servent-pas-à-grand-chose.
Le plus rapide aurait été de reprendre un code existant sur le net, mais c’est pas drôle. Alors amusé à le faire tout seul comme un grand.
Résultat
On commence par la démo disponible à cette adresse : http://delistage.net/tutos/tab-panel-simple-mootools/.
Et on passe maintenant au détail des différents fichiers et scripts nécessaires :
index.html
<div class="panel">
<ul class="panel-header">
<li class="panel-active"><a href="#" rel="panel-content-1">Content 1</a></li>
<li><a href="#" rel="panel-content-2">Content 2</a></li>
<li><a href="#" rel="panel-content-3">Content 3</a></li>
</ul>
<div id="panel-content-1" class="panel-content panel-display">
panel-content-1
</div><!-- #panel-content-1 -->
<div id="panel-content-2" class="panel-content">
panel-content-2
</div><!-- #panel-content-2 -->
<div id="panel-content-3" class="panel-content">
panel-content-3
</div><!-- #panel-content-3 -->
</div><!-- Panel 1 -->
Conteneur : un div ayant la classe panel, à ne pas changer.
La liste des onglets (ul) sans contrainte au niveau du nom de la classe. Chaque onglet est contenu dans une ligne (li) dont celui à sélectionner par défaut doit avoir la classe panel-active. On a ensuite l’onglet en lui-même sous forme de lien. L’attribut rel de cette balise doit contenir l’id de la div de contenu correspondant.
Différentes DIV de contenu doivent posséder un id (identique à celui rentré dans la balise rel de l’onglet) et la classe panel-content. Si vous souhaitez afficher un des panels par défaut, il suffit de lui ajouter la classe panel-display.
panels.js
Ce fichier contient la fonction en charge de la gestion des différents panels. Pas besoin de plus de commentaires que ceux qui sont dans le code je pense.
panelManager = function() {
// On parcourt chaque panel
$$('.panel').each(function(panelElt) {
// On récupère les onglets ...
var tabs = panelElt.getFirst('ul').getElements('a');
// Et on les parcourt à leur tour
tabs.each(function(tab) {
/*
* Ajout de l'évèment click
*/
tab.addEvent('click', function() {
// On regarde si le panel-content lié à cet onglet existe
var contentDiv = $(this.rel);
if(contentDiv != null) {
// Si c'est le cas, on masque les panel-content
panelElt.getElements('div').removeClass('panel-display');
// On déselectionne tous les onglets
panelElt.getFirst('ul').getElements('li').removeClass('panel-active');
// On affiche le panel-content sélectionné
contentDiv.addClass('panel-display');
// On sélectionne l'onglet
this.getParent().addClass('panel-active');
}
// Etant donné que notre onglet est un lien (a),
// on retourne faux pour annuler son action
return false;
});
});
});
}
Sur les pages contenant un ou plusieurs panels, il vous suffit d’appeler cette fonction très simplement :
<script type="text/javascript" src="panels.js"></script>
<script type="text/javascript">
window.addEvent('domready', function() {
panelManager();
});
</script>
panels.css
.panel { margin-bottom: 15px; }
.panel-header { border-bottom: 1px solid #333333; height: 30px; }
.panel-header li {
float: left;
height: 24px;
margin-right: 10px;
padding: 0 10px;
padding-top: 5px;
border: 1px solid #666666;
border-bottom: 1px solid #333333;
background-color: #fafafa;
}
.panel-header li a { color: #555555; text-decoration: none; }
.panel-header li:first-child { margin-left: 5px; }
.panel-header li.panel-active {
background-color: #eeeeee;
border: 1px solid #333333;
border-bottom: 1px dashed #333333;
color: #333333;
}
.panel-header li.panel-active a {
color: #333333;
text-decoration: none;
font-weight: bold;
}
.panel-content {
clear: both;
background-color: #eeeeee;
border: 1px solid #333333;
border-top: 0;
padding: 5px;
display: none;
}
.panel-display { display: block; }
Conclusion
Et voilà, vous avez là une petite fonction qui s’occupe d’afficher de la gestion des panels très simplement. Ça fonctionne avec Firefox 3.5, IE8 et Chrome 3.0 pour ceux que j’ai testé, mais étant donné que ça utilise Mootools, c’est censé être compatible avec la majorité des navigateurs. En cas de bugs ou de choses pas claires, les commentaires sont ouverts.
Aucun article à afficher.

janvier 23rd, 2010 à 13:39
Pas besoin de Mootools pour ça : http://javascript.internet.com/css/tab-view.html
Même sans JS c’est possible en 100% CSS : http://www.cssplay.co.uk/menu/one_page
janvier 23rd, 2010 à 14:13
Bien sûr que c’est possible de le faire sans Mootools voir même sans JS, c’est pour ça que j’ai précisé « avec Mootools ». :D Tout dépend après de l’utilisation et ce que tu utilises déjà sur le reste du site.
Par exemple la version par CSS que tu proposes ne présente pas le même comportement : les panels passent au dessus du texte, même si je suis sûr que ça doit être modifiable.
Par contre la version JS, ça serait dommage pour moi d’utiliser une librairie JS (en l’occurence Mootools dans mon cas) un peu partout sur le site et de pondre un code 100% JS natif/pur/sans librairie pour les panels. C’est facilement faisable, mais autant faire quelque chose d’un minimum cohérent pour faciliter les mises à jours en cas de besoin et utiliser les fonctionnalités proposées par le framework (comme la fonction Element.each() qui fait gagner pas mal de temps). Sans compter également que mon code fait un peu plus de 15 lignes sans commentaires, là où la solution que t’as linké en fait près du double. ;)
Et puis si un jour j’ai envie de rajouter un peu d’animation, c’est juste quelques petites lignes supplémentaires à rajouter. :)
avril 7th, 2010 à 7:16
Bonjour,
J’essaye d’utiliser ton script et de le combiner avec un effet scroll (http://demos111.mootools.net/Fx.Scroll). Pour le moment, ça ne marche pas…
avril 7th, 2010 à 9:13
Bonjour Tom,
Déjà attention aux versions. J’ai utilisé la version 1.2 pour tester ce script. Le lien que tu as donné présente les démos de la version 1.1. Etant donné que j’ai pas testé avec cette version, je peux pas te dire s’il fonctionne correctement ou pas avec (mais bon y’a pas de raison).
Ensuite tu veux simplement rajouter des effets de transition lors de chaque clic si j’ai bien compris. J’avoue que je ne me suis pas du tout penché sur le sujet quand je l’ai écrit. Par contre, je peux te conseiller ces quelques liens qui ressemblent à ce que j’ai cru comprendre que tu voulais réaliser :
- http://www.silverscripting.com/mootabs/ : pour une transition sur l’axe vertical,
- http://woork.blogspot.com/2009/01/ultra-versatile-slider-for-websites.html : pour une transition sur l’axe horizontal (à adapter par contre pour ajouter les onglets).
J’espère que ça pourra t’aider. ;)
avril 8th, 2010 à 7:02
Bonjour Sébastien, j’y suis finalement arrivée.
Je suis un autodidacte et j’ai quelques lacunes…
Mon soucis se situais dans les balises de liens, je ne croyais pas que l’on pouvais mettre id et rel ensemble.
Bref, bravo à toi pour ton travail.
-si tu veux voir l’effet aujourd’hui tu peux aller sur mon site en rajoutant /beta .
avril 8th, 2010 à 9:01
Hello,
Je viens d’y jeter un oeil et c’est plutôt pas mal comme effet. Je me suis permis de regarder ton code et il y a moyen de l’améliorer un peu.
- Plutôt que de faire :
window.addEvent('domready', function() {panelManager();
});
window.addEvent('domready', function(){
var scroll = new Fx.Scroll('wrapper', {
[...]
Tu peux tout faire dans la première fonction :
window.addEvent('domready', function() {panelManager();
var scroll = new Fx.Scroll('wrapper', {
[...]
Ca te fait gagner 2 lignes mais surtout diminue le nombre d’appels de fonction, ce qui fait au final gagner un peu de temps.
De la même manière, tu as ça :
event = new Event(event).stop();« event » est déjà une instance de la classe Event, donc tu n’as pas besoin de l’instancier de nouveau. Teste voir ceci qui devrait normalement fonctionner de la même manière :
event.stop();Et merci, je viens de voir une petite erreur dans mon code que je viens de corriger : la fonction panelManager() attend un paramètre mais je m’en sers pas par la suite.
mai 11th, 2010 à 8:12
Bonjour Sébastien, c’est toujours moi!
Super, je suis content de mon site et c’est en partie grâce à ton script.
Je me dis que certaines personnes ne comprennent pas forcément que le panel header est cliquable…
Du coup je souhaite ajouter en bas de chaque partie de contenu, un lien « suite » qui scroll vers la partie suivante. J’y suis arrivé.
Mais comment faire pour qu’au clic sur le « suite », la rubrique suivante s’active sur le panel header?
N’y arrivant pas, je me dis que toi, tu dois trouver la réponse en 10 secondes!
Thomas
mai 11th, 2010 à 9:03
Bonjour,
Si des personnes ne comprennent pas que c’est cliquable, il faut peut-être faire les onglets un petit peu plus gros.
Autrement sans avoir le temps de creuser plus (beaucoup de boulot), quand tu cliques sur un de ces liens, il faut qu’il déselectionne tous les onglets avec quelque chose comme (à adapter) :
// On déselectionne tous les ongletspanelElt.getFirst('ul').getElements('li').removeClass('panel-active');
Ensuite, il faut sélectionner l’onglet voulu comme par exemple :
this.getParent().addClass('panel-active');Ou alors vu ton code :
$('link1').addClass('panel-active');En espérant que ça puisse te mettre sur la voie.
Sébastien