L'esempio presentato è ottimizzato per Internet Explorer 5+ e Netscape Navigator 6+.
Sono stati utilizzati dei metodi e delle proprietà non spiegati nella trattazione del DOM, sui quali può essere necessario soffermarsi.
Questo script costruisce una serie di tag div e li aggiunge al body del documento tramite il metodo appendChild(). Prendendo ad esempio il primo elemento di menuPrincipale, la funzione init() aggiungerebbe al corpo del documento:
<div id="MENUP1" style="width:120px;height:20;top:5;left:5px;position:absolute"></div>
<!-- tralasciamo il resto delle caratteristiche CSS
relative alla formattazione del testo -->
Nella gerarchia del DOM, il document.body corrisponde al parentNode (nodo padre) di MENUP1, poiché il tag DIV identificato da questo ID è in esso contenuto. Allo stesso modo, per rilevare se è accaduto un evento di mouseover o di mouseout su questo elemento, è possibile aggiungere via codice i gestori onMouseOver e onMouseOut, come se avessimo scritto:
<div id="MENUP1" style="width:120px;height:20;top:5px;left:5px;position:absolute"
onMouseOver="show()" onMouseOut="hideIE()"></div>
<!-- tralasciamo il resto delle caratteristiche CSS
relative alla formattazione del testo -->
La sintassi differisce leggermente tra Internet Explorer e Navigator.
I menu secondari, che fanno apparire la lista con i link associati, sono costruiti in modo simile attraverso la funzione show(e), che prende come parametro l'evento e ad essa associato.
Ogni volta che la funzione show(e) viene richiamata se il mouse passa su uno degli elementi del menu principale, se esiste l'elemento corrispondente del menu secondario viene reso visibile, altrimenti viene creato. Prendendo ad esempio il primo sub-elemento, sarebbe come scrivere:
<div id="SUBMENU1" style="top:25;left:5px;position:absolute"
onMouseOut="hideIE()">
<ul>
<li><A HREF="#">sottomenu11</A></li>
<li><A HREF="#">sottomenu12</A></li>
</ul>
</div>
Gli elementi sono quindi richiamati attraverso l'ID, usando il metodo document.getElementById('id_name'). Per questo motivo gli ID sono sequenziali, MENUP1, MENUP2, MENUP-n e così via, secondo quanti se ne vogliono aggiungere.
<script language="JavaScript1.3"> <!-- var posL=5; // costante per la proprietà left var posT=5; // costante per la proprietà top var mpwidth=120; // costante per la proprietà width var mpheight=20; // costante per la proprietà height nel menu principale var mpfontSize=14; // costante per la proprietà fontSize nel menu principale var mpfontColor='#330033'; // costante per la proprietà fontColor nel menu principale var mpbackgroundColor='#BDBEA5'; // costante per la proprietà backgroundColor nel menu principale var mp2fontSize=12; // costante per la proprietà fontSize nel menu secondario var mp2fontColor='#330033'; // costante per la proprietà fontColor nel menu secondario var mp2backgroundColor='#EFE7CE'; // costante per la proprietà backgroundColor nel menu secondario // Array degli id assegnati al menu principale nel ciclo della funzione init() // al caricamento della pagina var menuPrincipale=new Array('MENUP1','MENUP2','MENUP3','MENUP4','MENUP5','MENUP6'); // Array degli id assegnati al menu secondario var sottoMenu=new Array('SUBMENU1','SUBMENU2','SUBMENU3','SUBMENU4','SUBMENU5','SUBMENU6'); // Array che rappresentano le voci della lista menu secondario e la proprietà href dei link // nell'esempio le voci sono numerate relativamente al submenu (sottomenu-nn) // mentre la proprietà href dirige verso la stessa pagina (#) var linksub11=new Array('sottomenu11','#'); var linksub12=new Array('sottomenu12','#'); var linksub21=new Array('sottomenu21','#'); var linksub22=new Array('sottomenu22','#'); var linksub31=new Array('sottomenu31','#'); var linksub32=new Array('sottomenu32','#'); var linksub41=new Array('sottomenu41','#'); var linksub42=new Array('sottomenu42','#'); var linksub51=new Array('sottomenu51','#'); var linksub52=new Array('sottomenu52','#'); var linksub61=new Array('sottomenu61','#'); var linksub62=new Array('sottomenu62','#'); var sub1=new Array(linksub11,linksub12); var sub2=new Array(linksub21,linksub21); var sub3=new Array(linksub31,linksub32); var sub4=new Array(linksub41,linksub42); var sub5=new Array(linksub51,linksub51); var sub6=new Array(linksub51,linksub51); var lista=new Array(sub1,sub2,sub3,sub4,sub5,sub6); // elementi da aggiungere al corpo del documento var elParent='DIV'; var elChild2='UL' var elChild3='LI'; var elChild4='A'; // funzione di caricamento iniziale function init(){ // variabile che determina un incremento per stabilire la proprietà left, // che si incrementa via via che vengono posizionati gli elementi addPosL=posL; for(i=0;i<menuPrincipale.length;i++){ // creo un elemento DIV con id MENUP-n appEl=document.createElement(elParent); appEl.setAttribute('id',menuPrincipale[i]); // aggiungo la proprietà style all'elemento with(appEl.style){ width = mpwidth + "px"; height = mpheight + "px"; top = posT; left = addPosL + "px"; color = mpfontColor; backgroundColor = mpbackgroundColor; textAlign = "center"; fontWeight = "bold" fontSize = mpfontSize + "px"; position = "absolute"; border = "1px " + mpfontColor + " solid"; visibility = 'visible'; } // incremento la posizione left addPosL+=mpwidth; // aggiungo la la label testuale (MENU1, MENU2, [...], MENUn) appEl.innerHTML =menuPrincipale[i]; // aggiungo 2 gestori di evento: // onMouseOver e onMouseOut if(appEl.attachEvent){ // modalità per MSIE 5+ // elemento.attachEvent('gestore_evento',riferimento_alla_funzione) // il riferimento alla funzione non deve essere seguito dalle parentesi // scrivere appEl.attachEvent("onmouseover", showIE()); sarebbe sbagliato appEl.attachEvent("onmouseover", show); appEl.attachEvent("onmouseout", hideIE); } else{ // modalità per Navigator 6+ // elemento.addEventListener('evento',riferimento_alla_funzione,booleano) // l'evento non deve essere preceduto da on ('mouseover', non 'onmouseover') // il riferimento alla funzione non deve essere seguito dalle parentesi // il booleano è posto a true se l'evento deve propagarsi nella gerarchia del documento, // altrimenti è posto a false if(appEl.addEventListener){ appEl.addEventListener("mouseover", show, false); appEl.addEventListener("mouseout", hideNN, false); } } // inserisco il menu nel documento document.body.appendChild(appEl); } } // la funzione richiamata per visualizzare il menu secondario function show(e){ // il presupposto è che la funzione sia richiamata quando il mouse passa sul menu // raccolgo il riferimento all'elemento dove è avvenuto l'evento di mouseover // mi aspetto che si riferisca a MENUP-n p=null; // variabile di appoggio per l'elemento che ha raccolto l'evento if(document.attachEvent) p=event.srcElement; // sintassi per MSIE else if(document.addEventListener) // sintassi per Navigator p=e.target; if(!p)return; if(p.id.indexOf('MENUP')!=-1){ // appoggio in una variabile il valore di posL addPosL=posL; for(i=0;i<menuPrincipale.length;i++){ if(p.id==menuPrincipale[i]){ // se esiste il menu secondario... if(document.getElementById(sottoMenu[i])){ //... lo rendo visibile! document.getElementById(sottoMenu[i]).style.visibility='visible'; } else{ // se non esiste lo creo appEl2=document.createElement(elParent); // gli assegno un id SUBMENU-n appEl2.setAttribute('id',sottoMenu[i]); // gli assegno uno stile with(appEl2.style){ top = posT + mpheight; left = addPosL + "px"; color = mp2fontColor; backgroundColor = mp2backgroundColor; textAlign = "center"; fontWeight = "bold" fontSize = mp2fontSize + "px"; position = "absolute"; border = "1px " + mp2fontColor + " solid"; visibility = "visible"; } // aggiungo la lista al submenu ulList=document.createElement(elChild2); // inserico gli elementi della lista for(j=0;j<lista[i].length;j++){ li=document.createElement(elChild3); for(z=0;z<lista[i][j].length;z++){ a=document.createElement(elChild4); a.innerHTML=lista[i][j][0]; a.setAttribute('href',lista[i][j][1]); } li.appendChild(a); ulList.appendChild(li); } // aggiungo il gestore mouseout al menu secondario: // quando il puntatore del mouse esce dal menu secondario // lo stesso deve essere reso non visibile if(appEl.attachEvent){ // gestione per MSIE appEl2.attachEvent("onmouseout", hideIE); } else if(appEl2.addEventListener){ // gestione per Navigator appEl2.addEventListener("mouseout", hideNN, false); } appEl2.appendChild(ulList); document.body.appendChild(appEl2); } } else{ // incremento la proprietà left addPosL+=mpwidth; if(document.getElementById(sottoMenu[i])){ // se esiste il submenu lo rendo non visibile document.getElementById(sottoMenu[i]).style.visibility='hidden'; } } } } } function hideIE(e){ // funzione specifica per MSIE 5.x // raccolgo il riferimento all'elemento dove è avvenuto l'evento if(!event.srcElement)return; p=event.srcElement; if(!p.id)return; if(p.id.indexOf('SUBMENU')!=-1){ // se il mouse è fuori dall'area del menu secondario, // rendo il menu secondario non visibile var altroElemento = null; if (e){ altroElemento = e.toElement; if(!altroElemento){ altroElemento = window.event.toElement; } } else if (window.event){ altroElemento = window.event.toElement; } if (nellElemento(p, altroElemento)){ return false; } else{ document.getElementById(p.id).style.visibility='hidden'; } } else // se il mouse è fuori dall'area del menu principale, // ma non sul submenu, rendo il menu secondario non visibile if(p.id.indexOf('MENUP')!=-1){ for(i=0;i<menuPrincipale.length;i++){ if(p.id==menuPrincipale[i]){ if(document.getElementById(sottoMenu[i])){ var altroElemento = null; if (e){ altroElemento = e.toElement; if(!altroElemento){ altroElemento = window.event.toElement; } } else if (window.event){ altroElemento = window.event.toElement; } if(altroElemento==document.getElementById(sottoMenu[i])){ return false; } else{ document.getElementById(sottoMenu[i]).style.visibility='hidden'; } } } } } return false; } function hideNN(e){ // funzione specifica per Navigator 6.x // come la funzione precedente, con le dovute differenze sintattiche rispetto a MSIE p=e.target; if(!p.id)return; if(p.id.indexOf('SUBMENU')!=-1){ var altroElemento = null; if (e){ altroElemento = e.relatedTarget; if (navigator.product == 'Gecko' && navigator.platform.indexOf('Linux') != -1 && !altroElemento){ altroElemento = e.originalTarget; } } else if (window.event){ altroElemento = window.event.toElement; } if(nellElemento(this, altroElemento)){ return false; } else{ document.getElementById(p.id).style.visibility='hidden'; } } else if(p.id.indexOf('MENUP')!=-1){ for(i=0;i<menuPrincipale.length;i++){ if(p.id==menuPrincipale[i]){ if(document.getElementById(sottoMenu[i])){ var altroElemento = null; if (e){ altroElemento = e.relatedTarget; if (navigator.product == 'Gecko' && navigator.platform.indexOf('Linux') != -1 && !altroElemento){ altroElemento = e.originalTarget; } } else if (window.event){ altroElemento = window.event.toElement; } if(altroElemento==document.getElementById(sottoMenu[i])){ return false; } else{ document.getElementById(sottoMenu[i]).style.visibility='hidden'; } } } } } return false; } // funzione che mi consente di vedere se un elemento è contenuto nell'altro // quindi se il parametro elemento è un parentNode // di submenu function nellElemento(submenu, elemento){ while (elemento && elemento != submenu){ elemento = elemento.parentNode; } if (elemento == submenu){ return true; } return false; } --> </script> |