Onglets reposant sur des div et du css

Soyez le premier à donner votre avis sur cette source.

Vue 26 571 fois - Téléchargée 3 642 fois

Description

Bonjour,

Il existe déjà pas mal de scripts pour générer des onglets, notamment celui de Wonesek repris par Djoad. Malheureusement, son utilisation ne convenait pas à mes besoins. J'ai donc développé ce script, qui utilise non pas un tableau et des bouts d'HTML dans le script, mais des DIV et des CSS. Si vous n'êtes pas familier avec la mise en page de DIV au moyen de CSS, je vous déconseille l'utilisation de ce code. Sans CSS, ça ne ressemble à rien ;)

Cette toute première version gère des onglets TEXTE, HTML, URL chargés dans une iframe, et du contenu chargé avec un peu d'Ajax.

NB : ce script repose sur le framework Prototype version 1.5.1.1 (http://www.prototypejs.org/). Le framework est fournit dans le zip. Ici encore, une petite mise en garde : si vous n'avez jamais mis le nez dans Prototype, vous allez avoir du mal à comprendre mon script.

Je ne suis pas un expert en javascript (je suis plus à l'aise avec PHP et l'actionscript). N'hésitez pas à remonter des bugs ou des optimisations possibles. Merci de votre indulgence ;)

Source / Exemple :


/*

  • Auteur : Daynos <devjs@daynos.net>
  • Class Onglet - version 0.1.20070703
  • /!\/!\/!\/!\/!\/!\/!\/!\/!\
  • REQUIERT LE FRAMEWORK JAVASCRIPT "PROTOTYPE"
  • Prototype JavaScript framework, version 1.5.1.1
  • (c) 2005-2007 Sam Stephenson
  • http://www.prototypejs.org/
  • /!\/!\/!\/!\/!\/!\/!\/!\/!\
  • /
Onglet = Class.create (); Onglet.prototype = { Version : '0.2.20070723', element : null, /* calque attribué au gestionnaire d'onglet */ initialize: function (element, cssId){ this.element = $(element); Object.extend (this.element, __OngletElement); this.element.initialize (cssId); }, // Ajouter un onglet de type TEXTE : charge du texte dans le div addOngletTexte: function (titre, contenu) { return this.element.addOnglet (0, titre, contenu); }, // Ajouter un onglet de type HTML : charge du code html dans le div addOngletHtml: function (titre, contenu) { return this.element.addOnglet (1, titre, contenu); }, // Ajouter un onglet de type URL : charge une page html dans une iframe addOngletUrl: function (titre, contenu) { return this.element.addOnglet (2, titre, contenu); }, // Ajouter un onglet de type AJAX : charge une contenu dynamique dans le div addOngletAjax: function (titre, contenu) { return this.element.addOnglet (3, titre, contenu); }, // Ajouter un onglet de type CALQUE : récupère le contenu d'un div existant et le place dans un onglet addOngletCalque: function (titre, contenu) { return this.element.addOnglet (4, titre, contenu); }, // Affiche l'onglet n°... setFocus: function (n) { this.element.setFocus (n); } } __OngletElement = { oMenu : null, /* calque contenant les boutons du menu */ oConteneur : null, /* calque contenant les contenus des onglets */ nOnglets : 0, /* nombre d'onglets liés */ cssId : null, /* préfixe des css à utiliser */ initialize: function (cssId) { this.cssId = cssId; // Ajouter le CSS this.addClassName (this.cssId); // Créer le calque qui contiendra les boutons du menu var menuDiv = document.createElement('div'); menuDiv.id = this.id + "_m"; this.appendChild (menuDiv); this.oMenu = $(menuDiv.id); Object.extend (this.oMenu, __MenuOnglet); this.oMenu.initialize (cssId); // Créer le calque qui contiendra l'ensemble des onglets var conteneurDiv = document.createElement('div'); conteneurDiv.id = this.id + "_c"; this.appendChild (conteneurDiv); this.oConteneur = $(conteneurDiv.id); Object.extend (this.oConteneur, __ConteneurOnglet); this.oConteneur.initialize (cssId); }, // Ajouter un onglet, retourne l'id du calque "contenu" addOnglet: function (type, titre, contenu) { this.nOnglets++; // créer un bouton pour l'onglet this.oMenu.addBouton (this.nOnglets, titre, this.cssId); // créer un calque pour accueillir le contenu de l'onglet return this.oConteneur.addContenu (this.nOnglets, type, contenu, this.cssId); }, setFocus: function (newFocusId) { var contenu = this.oConteneur.getElementId (newFocusId); var bouton = this.oMenu.getElementId (newFocusId); // Cacher tous les contenus this.oConteneur.immediateDescendants().each(Element.hide); // Griser tous les onglets this.oMenu.immediateDescendants().each(__BoutonOnglet.setInactive); // Afficher le contenu de l'onglet désiré $(contenu).show (); // Afficher le bouton de l'onglet désiré $(bouton).setActive (bouton); } } __MenuOnglet = { initialize: function () { this.addClassName (this.up(0).cssId + "_menu"); }, addBouton: function (ongletId, texte) { // Créer le calque du bouton var nouveauDiv = document.createElement('div'); nouveauDiv.id = this.getElementId (ongletId); nouveauDiv.ongletId = ongletId; this.appendChild (nouveauDiv); Object.extend ($(nouveauDiv.id), __BoutonOnglet); $(nouveauDiv.id).initialize (texte); }, getElementId: function (n) { return this.id + "_b" + n; } } __ConteneurOnglet = { initialize: function (cssId) { this.addClassName (cssId + "_conteneur"); }, addContenu: function (ongletId, type, contenu, cssId) { // Créer le calque du contenu var nouveauDiv = document.createElement('div'); nouveauDiv.id = this.getElementId (ongletId); this.appendChild (nouveauDiv); Object.extend ($(nouveauDiv.id), __ContenuOnglet); $(nouveauDiv.id).initialize (type, contenu, cssId); return nouveauDiv.id; }, getElementId: function (n){ return this.id + "_c" + n; } } __BoutonOnglet = { initialize: function (texte) { this.appendChild (document.createTextNode(texte)); this.setInactive (); // Surveiller les click sur le bouton this.observe ('click', function(event){ var elm = Event.element(event); $(elm).up(1).setFocus ($(elm).ongletId); }); }, setActive: function (element) { if (!element) {element = this;} var cssId = $(element).up(1).cssId; if ($(element).hasClassName (cssId + "_bouton_off")) { $(element).removeClassName (cssId + "_bouton_off"); } $(element).addClassName (cssId + "_bouton"); }, setInactive: function (element) { if (!element) {element = this;} var cssId = $(element).up(1).cssId; if ($(element).hasClassName (cssId + "_bouton")) { $(element).removeClassName (cssId + "_bouton"); } $(element).addClassName (cssId + "_bouton_off"); } } __ContenuOnglet = { initialize: function (type, valeur, cssId) { // gérer le contenu du div selon son type switch (type) { case 0: // mode texte this.appendChild (document.createTextNode(valeur)); break; case 1: // mode html this.update(valeur); break; case 2: // mode url if (Prototype.Browser.IE) { // IE n'aime pas les iframe créé via createElement. Alors il faut lui dédier un bout de code... var html = "<iframe id='" + this.id + "_i'" + " src='" + valeur + "'" + " scrolling='1'" + " frameborder='0'" + "></iframe>"; this.update (html); } else { var iframe = document.createElement ('iframe'); iframe.id = this.id+"_i"; iframe.src = valeur; iframe.scrolling = true; iframe.frameborder = "0"; this.appendChild (iframe); } // Appliquer le style css des iframes $(this.id+"_i").addClassName (this.up(1).cssId + "_iframe"); break; case 3 : // mode ajax var element = this; new Ajax.Request (valeur, { method: 'get', onSuccess: function (transport) { element.update(transport.responseText); } }); break; case 4 : // mode calque this.update ($(valeur).remove ().innerHTML); break; default: this.appendChild (document.createTextNode(valeur)); break; } // par défaut, tous les onglets sont invisibles. Utiliser setFocus pour déterminer l'onglet à afficher par défaut. this.hide (); // appliquer le style css au calque this.addClassName (cssId + "_contenu"); } }

Conclusion :


Je tâcherai de mettre à jour au fur et à mesure des remarques (s'il y en a :p)

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

cs_daynos
Messages postés
9
Date d'inscription
mercredi 26 février 2003
Statut
Membre
Dernière intervention
18 mai 2008

Bonjour,

Là comme ça le script n'a pas été prévu pour. Mais avec quelques modifications, ça doit être parfaitement faisable.

Par contre je suis désolé, mais je n'ai pas franchement le temps de m'y pencher moi-même pour l'instant. Si quelqu'un peut le faire, qu'il n'hésite pas à me tenir au courant, je mettrai à jour le script (sans oublier de le citer bien évidemment).

En tout cas merci pour ton commentaire ;).

PS en passant : j'ai supprimé mon adresse email "devjs@daynos.net", trop de spam ; c'est de ma faute, j'aurais pas du la mettre aussi lisible dans le code. Pour la nouvele adresse, mettez 'devfr' à la place de 'devjs'.
dlimouzin
Messages postés
11
Date d'inscription
mardi 31 décembre 2002
Statut
Membre
Dernière intervention
30 décembre 2008

Très intéressant.
Je me pose une question cependant.
Ayant à gérer une page très volumineuse (600Ko)
je voudrais savoir s'il était possible de gérer le chargement des onglets juste au click sur celui-ci de façon à réduire le temps d'attente initial.
Cordialement
cs_daynos
Messages postés
9
Date d'inscription
mercredi 26 février 2003
Statut
Membre
Dernière intervention
18 mai 2008

Article très intéressant, et je partage amplement cette vision.

Je n'ai jamais été favorable à l'utilisation massive de javascript. En fait je pense pouvoir dire que j'ai longtemps été de ces "anti-javacript parce que c'est pas activé partout". Je me remets en cause sur ce point de vue, parce que comme tout le monde, j'aime visiter des sites plaisant à consulter.

Je me suis donc mis dernièrement à javascript. Pas trop difficile en soit, il obéit aux mêmes normes que l'actionscript de Flash que je maîtrise assez bien. Par ailleurs, j'avais un travail à faire dans un cadre précis : des formulaires de consultation et de saisie à ajouter dans l'intranet de ma boite. C'est à dire un parc informatique "maîtrisé", où l'on sait comment son paramétrés toutes les machines, la version des navigateurs, la taille des écrans, les compétences du personnel, etc.
Sachant que javascript était correctement installé et interprété sur toutes les machines, et que le serveur était en local sur un réseau 100mbps (côté client), ça m'ôtait quand même pas mal de soucis.

Pour des soucis "d'ergonomie du produit final", une présentation en onglet était préférée. A cela s'ajoutait un autre impératif : on devait pouvoir passer d'un onglet à l'autre sans que les modifications apportées au contenu d'un onglet soient perdues, ni écrasent le contenu de la base avant que l'ensemble des modifications ait été validé.

J'avais bien sûr l'option des sessions, de la mise en "base de donnée temporaire", mais bon, j'ai opté pour des onglets utilisant la balise "DIV" et du javascript. Ca me smeblait être la solution la plus simple. Et puis j'avais envi de faire du javascript pour ma culture personnelle :D. Ce dernier point n'est pas à négliger, je dois l'avouer, j'avais envie de profiter de ce développement relativement libre pour tester les possibilités actuelles de javascript. Je pense en particulier à tout ce qui tourne autour du terme "AJAX". Ce terme existe depuis quelques années déjà, mais je n'avais jamais eu l'occasion de me pencher sérieusement sur le sujet jusque là.




Bref c'est donc dans un environnement 100% compatible javascript et super rapide que j'ai conçu la première version de ce script. Ce qui explique que je ne me sois pas vraiment préoccupé du rendu avec javascript désactivé, ni du poids total du script (enfin du framework qu'il requiert ;)).
Mamoune2005
Messages postés
9
Date d'inscription
dimanche 27 mars 2005
Statut
Membre
Dernière intervention
3 novembre 2008

Je suis un peu de l'école qui est exposée dans l'article suivant :
http://pompage.net/pompe/separation/
et donc javascript, oui, mais seulement pour modifier (en améliorant, bien sur) le comportement.

Donc s'il y a bien des calques fonctionnels quand le javascript n'est pas actif, tu as entièrement comblé ma critique. Je n'ai pas le temps de regarder maintenant.

Même remarque que Moaleboss, le validateur HTML ne valide que le HTML, ..., donc si ton javascript est bien dans ces balises, c'est valide.
moaleboss
Messages postés
19
Date d'inscription
lundi 20 janvier 2003
Statut
Membre
Dernière intervention
24 juillet 2007

Salut,

En Javascript, quand tu met du code HTML, et que tu ferme une balise, il faut que les '/' soit précédés du caractère d'échappement '\'
Exemple :
oOnglet.addOngletHtml ("Onglet HTML", "Pour tester
");
Devient :
oOnglet.addOngletHtml ("Onglet HTML", "<h1>Pour tester<\/h1>");

Au passage, le validateur de code HTML du W3C ne corrige pas les erreurs Javascript ;-)

Bonne prog

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.

Du même auteur (cs_daynos)