Menu vertical - sous-niveaux infinis - facilement modifiable

Description

Suite à un premier menu avec un seul sous-niveau possible (http://www.javascriptfr.com/code.aspx?ID=32842), et quelques remarques et conseils (merci beaucoup coucou747), voici un menu basé sur le premier, mais avec un nombre infini de sous niveaux.
Pour se repérer, les titres dont le sous menu est ouvert gardent une couleur différente (la meme que quand la souris les survole), et les sous menus sont indiqués par un > en fin de ligne.

La création des menus est assez facile, mais il ne faut pas se tromper dans les numéros de sous menus... je n'ai pas trouvé comment faire plus simple.

La plupart des parametres (voir tous) sont modifiables par les variables définies en haut du fichier .js

Source / Exemple :


//Définition des variables
var Liste=new Menu();		//Menu contenant les menus princpaux
var Largeur=165,Hauteur=20;	//Largeur des menus et sous menus
var DivTop=20;DivLeft=20;	//Position du menu par rapport au bord de la feuille (en pixels)
var Open;					//Variable contenant la liste des sous menus affichés
var MOut='#FFF8F0';			//Couleur des menus non survolés
var MOver='#FFF8F0';		//Couleur des menus survolés
var SMOut='#F0FFF0';		//Couleur des sous menus non survolés
var SMOver='#FFF0F0';		//Couleur des sous menus survolés
var Timer=2000,Time;		//Timer : Temps à attendre pour que le menu s'efface (nul => désactivé)
var LgID;
var Affichage,Com;

//Définition des menus et sous menus
Liste.State=1;
Liste.nb=0;
Liste.ID=Open="Liste";
LgID=Open.length;

Liste.AddM("Menu 1");
	Liste.SMenu[0].AddM("Sous-Menu 1.1","javascript:alert('Sous-Menu 1.1')");
		Liste.SMenu[0].SMenu[0].AddM("Sous-Menu 1.1.1","javascript:alert('Sous-Menu 1.1.1')");
		Liste.SMenu[0].SMenu[0].AddM("Sous-Menu 1.1.2","javascript:alert('Sous-Menu 1.1.2')");
		Liste.SMenu[0].SMenu[0].AddM("Sous-Menu 1.1.3","javascript:alert('Sous-Menu 1.1.3')");
			Liste.SMenu[0].SMenu[0].SMenu[2].AddM("Sous-Menu 1.1.3.1","javascript:alert('Sous-Menu 1.1.3.1')");
				Liste.SMenu[0].SMenu[0].SMenu[2].SMenu[0].AddM("Sous-Menu 1.1.3.1.1","javascript:alert('Sous-Menu 1.1.3.1.1')");
				Liste.SMenu[0].SMenu[0].SMenu[2].SMenu[0].AddM("Sous-Menu 1.1.3.1.2","javascript:alert('Sous-Menu 1.1.3.1.2')");
					Liste.SMenu[0].SMenu[0].SMenu[2].SMenu[0].SMenu[1].AddM("Sous-Menu 1.1.3.1.2.1","javascript:alert('Sous-Menu 1.1.3.1.2.1')");
			Liste.SMenu[0].SMenu[0].SMenu[2].AddM("Sous-Menu 1.1.3.2","javascript:alert('Sous-Menu 1.1.3.2')");
			Liste.SMenu[0].SMenu[0].SMenu[2].AddM("Sous-Menu 1.1.3.3","javascript:alert('Sous-Menu 1.1.3.3')");
		Liste.SMenu[0].SMenu[0].AddM("Sous-Menu 1.1.4","javascript:alert('Sous-Menu 1.1.4')");
	Liste.SMenu[0].AddM("Sous-Menu 1.2","javascript:alert('Sous-Menu 1.2')");
		Liste.SMenu[0].SMenu[1].AddM("Sous-Menu 1.2.1","javascript:alert('Sous-Menu 1.2.1')");
		Liste.SMenu[0].SMenu[1].AddM("Sous-Menu 1.2.1","javascript:alert('Sous-Menu 1.2.2')");
	Liste.SMenu[0].AddM("Sous-Menu 1.3","javascript:alert('Sous-Menu 1.3')");

Liste.AddM("Menu 2");
	Liste.SMenu[1].AddM("Sous-Menu 2.1","javascript:alert('Sous-Menu 2.1')");
		Liste.SMenu[1].SMenu[0].AddM("Sous-Menu 2.1.1","javascript:alert('Sous-Menu 2.1.1')");
		Liste.SMenu[1].SMenu[0].AddM("Sous-Menu 2.1.2","javascript:alert('Sous-Menu 2.1.2')");
			Liste.SMenu[1].SMenu[0].SMenu[1].AddM("Sous-Menu 2.1.2.1","javascript:alert('Sous-Menu 2.1.2.1')");
			Liste.SMenu[1].SMenu[0].SMenu[1].AddM("Sous-Menu 2.1.2.2","javascript:alert('Sous-Menu 2.1.2.2')");
			Liste.SMenu[1].SMenu[0].SMenu[1].AddM("Sous-Menu 2.1.2.3","javascript:alert('Sous-Menu 2.1.2.3')");
	Liste.SMenu[1].AddM("Sous-Menu 2.2","javascript:alert('Sous-Menu 2.2')");
	Liste.SMenu[1].AddM("Sous-Menu 2.3","javascript:alert('Sous-Menu 2.3')");
	Liste.SMenu[1].AddM("Sous-Menu 2.4","javascript:alert('Sous-Menu 2.4')");

Liste.AddM("Menu 3","javascript:alert('Menu 3')");
	Liste.SMenu[2].AddM("Sous-Menu 3.1","javascript:alert('Sous-Menu 3.1')");
	Liste.SMenu[2].AddM("Sous-Menu 3.2","javascript:alert('Sous-Menu 3.2')");
		Liste.SMenu[2].SMenu[1].AddM("Sous-Menu 3.2.1","javascript:alert('Sous-Menu 3.2.1')");
			Liste.SMenu[2].SMenu[1].SMenu[0].AddM("Sous-Menu 3.2.1.1","javascript:alert('Sous-Menu 3.2.1.1')");
			Liste.SMenu[2].SMenu[1].SMenu[0].AddM("Sous-Menu 3.2.1.2","javascript:alert('Sous-Menu 3.2.1.2')");
		Liste.SMenu[2].SMenu[1].AddM("Sous-Menu 3.2.2","javascript:alert('Sous-Menu 3.2.2')");
	Liste.SMenu[2].AddM("Sous-Menu 3.3","javascript:alert('Sous-Menu 3.3')");

Liste.AddM("Menu 4");
	Liste.SMenu[3].AddM("Sous-Menu 4.1","javascript:alert('Sous-Menu 4.1')");

Liste.AddM("Menu 5","javascript:alert('Menu 5')");

//Définition des fonctions
	//Définition de l'objet Menu
function Menu(){
	this.Titre;				//Titre du menu
	this.State;				//Positif : Menu affiché ; Négatif : Menu masqué
	this.nb;				//Nombre de sous menus
	this.ID;				//Identifiant du menu ou sous menu
	this.SMenu=new Array();
	this.Lvl=Level;
	this.AddM=AddMenu;
	this.Aff=AffMenu;
	this.AffB=AffBetween;
}

	//Fonction chargée de créer les sous menus
		//Nom : Texte qui sera affiché sur la page HTML
		//Lien (optionel) : Lien hypertexte associé à l'entrée du menu
		//Dest (optionel) : Frame cible du lien
function AddMenu(Nom,Lien,Dest){
	this.SMenu[this.nb]=new Menu();
	if(Lien)
		if(Dest)this.SMenu[this.nb].Titre='<a href="'+Lien+'" target="'+Dest+'">'+Nom+'</a>';
		else this.SMenu[this.nb].Titre='<a href="'+Lien+'">'+Nom+'</a>';
	else this.SMenu[this.nb].Titre=Nom;
	this.SMenu[this.nb].State=-1;
	this.SMenu[this.nb].nb=0;
	this.SMenu[this.nb].ID=this.ID+'.SMenu['+this.nb+']';
	this.nb++;
}

	//Fonction chargée de donner le nombre de sous niveaux maximum
		//Level de l'objet
function Level(Lvl){
	var i;
	LvlMax=Lvl?LvlMax:0;
	LvlMax=LvlMax<Lvl?Lvl:LvlMax;
	if(this.nb)
		for(i=0;i<this.nb;i++){
			this.SMenu[i].Lvl(Lvl+1);
		}
	return LvlMax;
}

	//Fonction chargée d'afficher ou masquer les menus
		//Level : Place de la case en largeur
		//Num : Place de la case en hauteur
function AffMenu(Level,Num){
	var i,ColorOut,ColorOver;
	ColorOut=(Level)?SMOut:MOut;
	ColorOver=(Level)?SMOver:MOver;
	document.getElementById('ListeLvl'+Level).style.top=Num*Hauteur+DivTop;
	Affichage="";
	if(this.State>0){
		Affichage="<table bgColor="+ColorOut+">";
		for(i=0;i<this.nb;i++){
			Affichage+="<tr bgColor='";
			Affichage+=this.SMenu[i].State>0?ColorOver:ColorOut;
			Affichage+="' ";
			Affichage+="onMouseOut='"+this.SMenu[i].ID+".State>0?this.setAttribute(\"bgColor\",\""+ColorOver+"\"):this.setAttribute(\"bgColor\",\""+ColorOut+"\");";
			Affichage+=Timer?"Time=setTimeout(\""+Open.substring(0,LgID)+".AffB(0,0)\","+Timer+")' ":"' ";
			Affichage+="onMouseOver='this.setAttribute(\"bgColor\",\""+ColorOver+"\");";
			Affichage+=Timer?"clearTimeout(Time);":"";
			Affichage+=this.SMenu[i].Lvl(0)?this.SMenu[i].ID+".AffB("+(Level+1)+","+(Num+i)+")' ":"' ";
			Affichage+="><td width="+(Largeur-12)+" height="+Hauteur+">";
			Affichage+=this.SMenu[i].Titre;
			Affichage+="</td><td width=10>";
			Affichage+=this.SMenu[i].nb?">":"";
			Affichage+="</td></tr>";
		}
	Affichage+="</table>";
	}
	document.getElementById('ListeLvl'+Level).innerHTML=Affichage;
	document.getElementById('ListeLvl'+Level).style.visibility="visible";
}

	//Fonction chargée d'afficher le sous menu sélectionné
		//Level : Niveau du sous menu à afficher
		//Num : Numéro du sous menu à afficher
function AffBetween(Level,Num){
	for(i=(LgID+Level*9),j=0;i<=Open.length;i+=9,j++)eval(Open.substring(0,i)+".State=-1");
	this.State=-this.State;
	if(LgID+Level*9<=Open.length){
		if(Level>1){
			Com=Open.substring(0,LgID+(Level-1)*9)+".State=1;"+Open.substring(0,LgID+(Level-1)*9)+".Aff("+(Level-1)+",(";
			for(i=12;i<LgID+(Level-1)*9;i+=9)Com+=Open.charAt(i)+"+";
			Com+="0))";
		}
		else Com=Open.substring(0,LgID)+".State=1;"+Open.substring(0,LgID)+".Aff(0,0)";
		eval(Com);
	}
	for(i=Level;i<Liste.Lvl(0);i++){
		document.getElementById('ListeLvl'+i).style.visibility="hidden";
	}
	this.Aff(Level,Num);
	Open=this.ID;
}

	//Fonction chargée d'afficher les menus au chargement de la page
function InitMenu(){
	var i;
	for(i=0;i<Liste.Lvl(0);i++){
		document.write("<div ID='ListeLvl"+i+"' style='position:absolute;left:"+(i*(Largeur+4)+DivLeft)+"'></div>");
	}
	Liste.Aff(0,0);
}

Conclusion :


Pour l'inclure dans une page HTML, il suffit de mettre cette ligne dans le <head> :
<script language=JavaScript src="Menu.js">

et ces lignes dans le <body> (pas dans l'événement onload, ca ne fonctionne pas):
<script language=JavaScript>
InitMenu();
</script>

Bugs connus :
- Pour les menus contenant des sous menus et un lien, le lien ne fonctionne pas dans IE (pour la version précedante, c'etait dans FireFox que ca ne fonctionnait pas...)
- De temps en temps, le timer ne fonctionne pas, il suffit de repasser sur le menu pour que ca fonctionne.

Codes Sources

A voir également

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.