Ce n’est pas toujours évident de choisir un style de menu qui est simple et facilement adaptable à plusieurs situations. C’est mon bon ami Benoît St-André qui m’a fait remarquer la beauté du menu de HORDE.
Après un examen du code source, je me suis rendu compte qu’effectivement, ce menu est terriblement efficace, facilement modifiable et d’une très grande beauté au niveau de la programmation. Ce menu est tellement simple que Benoît a même décidé de modifier en conséquence les rubriques du Cyberfolio.
Alors, pourquoi ne pas en faire profiter les lecteurs-développeurs de LinuxEduQuébec qui aimeraient ajouter un tel menu dans leurs propres applications ?
Voici le source avec les commentaires appropriés qui devraient vous permettre de bien le comprendre. Les commentaires sont relatifs à la ligne de code qui apparaît immédiatement sous eux.
Remarque : Même si vous n’êtes pas programmeur, jetez tout de même un oeil « transversal » sur ce code-source. Peut-être vous prendra-t-il le goût d’explorer un peu plus l’univers de la programmation.

Pour essayer ce menu, téléchargez et décompactez le document joint dans un dossier. Puis, de votre navigateur, lancez le fichier menu.html dudit dossier. L’archive contient le fichier menu.html de même que les deux petites images triangulaires. Évidemment, pour l’utiliser dans vos propres applications, vous pouvez supprimer tous les commentaires car ils n’y sont qu’à des fins didactiques.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Menu à la Horde </title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<!--
On a besoin d'un style qui affichera (ou non) les sous-menus.
Au chargement de la page web, on décide toujours de NE PAS
afficher les sous-menus.
Par le javascript, on verra plus loin comment modifier l'attribut display (car on veut le modifier en "block" lorsqu'on clique sur un menu) de la classe para.
Les autres éléments des styles s'appliquent aux différents niveaux des menus.
-->
<style type="text/css">
.para {
display: none
}
.niveau0 {
font-size:1.8em;
}
.niveau1 {
font-size:80%;
border-left:1px dotted blue;
padding-left:0.5em;
color:green;
}
.niveau2 {
padding-left:0.5em;
border-left:1px dotted red;
font-size:90%;
}
body a:link {text-decoration:none;}
body a:visited {text-decoration:none;}
body a:hover {text-decoration:underline;}
</style>
<!--
Le javascript ! Le but est le suivant : lorsqu'on clique sur un item du menu une première fois, si cet item possède un ou des sous-menus, on les affiche. Si on clique sur un item du menu alors que le sous-menu de cet item est déjà affiché, on ferme le sous-menu.
De plus, on doit modifier l'image qui suit l'item du menu : une flèche à droite lorsque le menu est dépliable. Et une flèche vers le bas lorsque le sous-menu est déjà déplié.
-->
<script type="text/javascript">
/*
Généralités :
La fonction toggle a besoin d'une variable qui est en fait un tableau.
Les indices de ce tableau seront les noms des menus qui ont des sous-menus.
Dans notre exemple, les noms sont «construire» et «construire2».
On crée ainsi les ID des menus (menu_construire, menu_construire2) et les ID des images (arrow_construire et arrow_construire2) de manière à ce que la fonction puisse changer le contenu du style PARA de ces balises et le contenu de la balise IMG.
shown est une variable qui contient TRUE ou FALSE.
Le fait de donner le type ARRAY à shown à pour conséquence qu'on peut créer une foule de menus et sous-menu et sous-sous-menus : il suffit juste de donner des noms différents aux ID qui leur sont associés.
*/
var shown = new Array();
/*
La fonction toggle est appelée aussitôt qu'on clique sur un élément du menu.
*/
function toggle(i)
{
/*
La ligne ci-dessous est une opération ternaire.
a = b ? "linux" : "windows"
est une manière courte, rapide et... ésotérique d'écrire
if (b) {a = "linux";} else {a="windows";}
Supposons donc qu'on a cliqué sur l'item menu1. Plus bas vous voyez que la fonction toggle(construire) est alors appelée. Donc, i=constuire.
La page interprète la ligne de code ainsi :
Si shown[constuire] vaut 1 (ce qui est faux, car on n'a encore donné aucune valeur à shown[constuire]), on met dans shown[constuire] la valeur 1, sinon on met false.
Donc, shown[constuire] contient maintenant la valeur FALSE (ce qui est équivalent à 0).
*/
shown[i] = shown[i] ? shown[i] : false;
/*
Hum... on assigne maintenant à shown[constuire] LE CONTRAIRE de sa valeur. Si c'était 0, on assigne 1 et si c'était 1 on assigne 0.
Donc, après avoir cliqué sur menu1 LA PREMIÈRE FOIS, shown[constuire] contient la valeur 1. Ouf !
Cette idée est brillante. En effet, supposons que l'on clique UNE DEUXIÈME FOIS sur l'item menu1, alors, si vous refaites la logique des ces deux lignes, vous verrez que shown[construire] vaudra maintenant 0. C'est dans dans ces deux petites lignes, qu'on prépare le basculage des items du menu.
*/
shown[i] = !shown[i];
/*
On crée maintenant deux variables. La première (current) servira dans la classe PARA du style de la page, la seconde permettra de charger l'image arrow_expanded.gif ou arrow_collapsed.gif.
*/
var current = shown[i] ? 'block' : 'none';
var state = shown[i] ? 'expanded' : 'collapsed';
/*
ON vérifie maintenant si le navigateur comprend la fonction getElementByID et en même temps, on s'accapare du ID de menu_constuire.
Dans le HTML plus bas, vous verrez une balise <DIV id='menu_construire' class='para'>.
document.getElementById('menu_constuire) s'assure qu'elle travaille dans cette balise DIV.
*/
if (document.getElementById && document.getElementById('menu_' + i)) {
/*
On modifie alors le style display de la balise DIV dont le ID est menu_construire par le contenu de la variable current. Au premier clic sur menu1, current contient la valeur block, ce qui indique au navigateur D'AFFICHER tout ce qui se trouve dans ce DIV.
Notez qu'un deuxième clic sur menu1 assignera la valeur NONE à current . Ce qui aura pour effet de CACHER le contenu du DIV.
*/
document.getElementById('menu_' + i).style.display = current;
/*
Au premier clic sur menu1, on modifie l'image source de la balise IMG dont le ID est menu_construire par l'image array_expanded.gif.
Notez qu'un deuxième clic sur menu1 assignera la valeur collapsed à state . Ce qui aura pour effet de mettre l'image arrow_collapsed.gif comme source de la balise IMG.
*/
document.getElementById('arrow_' + i).src = 'arrow-' + state + '.gif';
}
/*
Il est possible que vous ayez un (vieux) navigateur qui utilise le JScript au lieu du JavaScript.. Si c'est le cas, la fonction utilisera la propriété document.all au lieu de la méthode getElementByID.
*/
else
if (document.all && document.all['menu_' + i]) {
document.all['menu_' + i].style.display = current;
document.all['arrow_' + i].src = 'arrow-' + state + '.gif';
}
}
</script>
</head>
<body>
<!-- On donne le style niveau0 à toutes les rubriques du menu principal -->
<div class="niveau0">
<!--
href="#" signifie qu'on envoie l'hyperlien vers ... rien. En fait, la finale du unclick (return=false) est bien suffisant ici. En effet, même si vous mettiez le lien "href="lien.html" par exemple, ce "return=false" ferait en sorte que ce lien ne serait jamais appelé.
Sur un click, on appelle la fonction toggle('construire'). Notez que le id de l'image est arrow_construire et le id du div qui suit plus bas est menu_construire. Il est donc très important, si vous ajouter des rubriques, de conserver le même mot (qui doit être unique pour chaque rubrique).
Ex. toggle('monmotunique'), id="arrow_monmotunique" et id="menu_monmotunique".
Voir plus bas pour la deuxième rubrique principale.
onmouseover... permet d'afficher le texte dans la barre de statu du navigateur (en général, au bas de l'écran). Cest assez intéressant, car l'internaute voit un texte au lieu de l'adresse de l'hyperlien.
title est l'attribut qui permet d'affichier une bulle explicative lorsque l'internaute laisse sa souris sur le lien.
this.blur permet d'enlever le focus sur le lien. Remplacez blur par focus (this.focus) pour voir la différence !
-->
<a href="#" onclick="toggle('construire'); this.blur(); return false;" onmouseover="window.status='Construire'; return true;" title="Construire">Menu1
<img src="arrow-collapsed.gif" border="0" id="arrow_construire" alt="construire"/></a>
<!-- Début du div ayant la classe PARA. C'est cette classe qui au départ possède l'attribut DISPLAY=NONE.
Vous devez créer un div class=para id="menu_NomIdentiqueAuNomDuParentDeCeSousMENU" pour toutes les rubriques ayant des sous-menus.
-->
<div class="para" id="menu_construire">
<!-- niveau1 est tout simplement le style qui est appliqué à toutes les sous-rubriques (les sous-menus) d'une rubrique principale.
-->
<div class="niveau1">
<!-- Remarquez le return=true parce qu'on veut qu'en cliquant, on aille vraiment vers lien1.html
Remarquez aussi qu'il n'y a pas d'appel vers toggle(). En effet, cette sous-rubrique n'a pas de sous-menu.
-->
<a href="lien1.html" onclick="this.blur()" onmouseover="window.status='Pour aller vers le lien1'; return true;" title="Lien no. 1" > Sous-Menu1.1</a>
<br>
<!-- Voici maintenant un sous-menu qui possède lui-même des sous-menus. L'ensemble s'appelle constuire2. Remarquez que construire2 revient dans le id de IMG (arrow_construire2) et dans le id du DIV class PARA (menu_construire2)
-->
<a href="#" onclick="toggle('construire2'); this.blur(); return false;" onmouseover="window.status='Sous-menu'; return true;" title="Un beau sous-menu"> Sous-Menu1.2<img src="arrow-collapsed.gif" border="0" id="arrow_construire2" alt="construire"/></a><br>
<div class="para" id="menu_construire2">
<div class="niveau2">
<a href="lien2.html" onclick="this.blur()" onmouseover="window.status='Vers le lien no. 2'; return true;" title="Lien 2" > Sous-Sous-Menu1.2.1</a>
<br>
<a href="lien3.html" onclick="this.blur()" onmouseover="window.status='Vers le lien no. 3'; return true;" title="Lien no. 3" > Sous-Sous-Menu1.2.2</a>
</div>
</div>
<a href="lien4.html" onclick="this.blur()" onmouseover="window.status='Lien no. 4'; return true;" title="Lien 4" >Sous-Menu1.3</a>
<br>
<a href="lien5.html" onclick="this.blur()" onmouseover="window.status='Vers le lien no.5'; return true;" title="Lien 5" > Sous-Menu1.4</a>
</div>
</div> <!-- fin du sous-menu au Menu1 : id=menu_construire -->
</div> <!-- fin du style niveau 0 -->
<div class="niveau0">
<!-- Deuxième item du menu principal. Il est affecté par le style niveau0
-->
<a href="#" onclick="toggle('construire3'); this.blur(); return false;" onmouseover="window.status='La deuxième rubrique'; return true;" title="Rubrique no. 2">Menu2
<img src="arrow-collapsed.gif" border="0" id="arrow_construire3" alt="fleche"/></a>
<div class="para" id="menu_construire3">
<div class="niveau1">
<a href="#" onclick="toggle('construire4'); this.blur(); return false;" onmouseover="window.status='Un autre sous-menu'; return true;" title="Rubrique 2.1"> Sous-Menu2.1<img src="arrow-collapsed.gif" border="0" id="arrow_construire4" alt="fleche" /></a><br>
<div class="para" id="menu_construire4">
<div class="niveau2">
<a href="lien6.html" onclick="this.blur()" onmouseover="window.status='Un autre lien...'; return true;" title="Lien no. 6" > Sous-Sous-Menu2.1.1</a>
<br>
<a href="lien7.html" onclick="this.blur()" onmouseover="window.status='Lien 7'; return true;" title="Lien no. 7" > Sous-Sous-Menu2.1.2</a>
</div>
</div>
<a href="lien8" onclick="this.blur()" onmouseover="window.status='Finalement...'; return true;" title="Lien no. 8" > Sous-Menu2.2</a>
</div>
</div>
</div> <!-- fin du style niveau 0 -->
</body>
</html>



