- Sat
- 4
- Oct
- 08
Menu a tendina multilivello crossbrowser con jQuery e Css
Di in Cascade Style Sheet, Javascript, jQuery Controls: +-close
Crossbrowser Multi Level Drop Down Menu Con jQuery e Css
I menu a tendina sono molto utilizzati nelle applicazioni web, e molto spesso per crearli si ricorre a chilometri di codice javascript, scelta che potrebbe comportare diverse problematiche a livello di portabilità, accessibilità, efficienza ecc… Non è il caso del menù che andremo a vedere tra poco, interamente realizzato dal sottoscritto, creato quasi completamente utilizzando ’semplice’ codice css con un pizzico di jQuery. Prima di buttarmi in questo lavoro ho effettuato diverse ricerche per vedere se ciò di cui avevo bisogno fosse già stato creato da qualcuno, ed in effetti, in molti hanno già creato cose abbastanza simili. Ciò che mi ha fatto decidere di creare qualcosa ex novo è stata la difficoltà di riadattare il codice altrui alle mie esigenze, e spero che con le spiegazioni che darò qui di seguito nessuno vada incontro alle medesime problematiche.
Ecco subito un esempio di cosa andremo ad ottenere e qui di seguito il codice:
index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="it" lang="it">
<head>
<link rel="stylesheet" type="text/css" media="screen" href="./styles/style.css" />
<script type="text/javascript" src="./js/jquery.js"></script>
<script type="text/javascript" src="./js/menu.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Drop Down Menu</title>
</head>
<body>
<div id="navigator">
<ul>
<li><p><a>Voce 1</a></p>
<ul>
<li><p><a>Sub Voce 1-1</a></p>
<ul>
<li><p><a>Sub Voce 1-1-1</a></p>
<ul>
<li><p><a>Sub Voce 1-1-1-1</a></p></li>
<li><p><a>Sub Voce 1-1-1-2sssssss sssssssss ssssss</a></p></li>
<li><p><a>Sub Voce 1-1-1-3</a></p></li>
<li><p><a>Sub Voce 1-1-1-4</a></p>
<ul>
<li><p><a>Sub Voce 1-1-1-4-1</a></p></li>
<li><p><a>Sub Voce 1-1-1-4-2</a></p></li>
<li><p><a>Sub Voce 1-1-1-4-3</a></p></li>
<li><p><a>Sub Voce 1-1-1-4-4</a></p></li>
<li><p><a>Sub Voce 1-1-1-4-5</a></p></li>
<li><p><a>Sub Voce 1-1-1-4-6</a></p></li>
</ul>
</li>
<li><p><a>Sub Voce 1-1-1-5</a></p></li>
<li><p><a>Sub Voce 1-1-1-6</a></p></li>
</ul>
</li>
<li><p><a>Sub Voce 1-1-2</a></p>
<ul>
<li><p><a>Sub Voce 1-1-2-1</a></p></li>
<li><p><a>Sub Voce 1-1-2-2</a></p></li>
<li><p><a>Sub Voce 1-1-2-3</a></p></li>
<li><p><a>Sub Voce 1-1-2-4</a></p></li>
<li><p><a>Sub Voce 1-1-2-5</a></p></li>
<li><p><a>Sub Voce 1-1-2-6</a></p></li>
<li><p><a>Sub Voce 1-1-2-7</a></p></li>
</ul>
</li>
<li><p><a>Sub Voce 1-1-3</a></p></li>
</ul>
</li>
<li><p><a>Sub Voce 1-2</a></p></li>
</ul>
</li>
<li><p><a>Voce 2</a></p></li>
<li><p><a>Voce 3</a></p>
<ul>
<li><p><a>Sub Voce 3-1</a></p></li>
<li><p><a>Sub Voce 3-2</a></p>
<ul>
<li><p><a>Sub Voce 3-2-1</a></p></li>
<li><p><a>Sub Voce 3-2-2</a></p></li>
<li><p><a>Sub Voce 3-2-3</a></p></li>
</ul>
</li>
</ul>
</li>
<li><p><a>Voce 4</a></p></li>
<li><p><a>Voce 5</a></p></li>
<li><p><a>Voce 6</a></p></li>
</ul>
</div>
</body>
</html>
style/style.css
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-size: 100%;
vertical-align: baseline;
background: transparent;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
/* remember to define focus styles! */
:focus {
outline: 0;
}
/* remember to highlight inserts somehow! */
ins {
text-decoration: none;
}
del {
text-decoration: line-through;
}
/* tables still need 'cellspacing="0"' in the markup */
table {
border-collapse: collapse;
border-spacing: 0;
}
span {
display: none;
}
#navigator {
width: 990px;
height: 21px;
background-color: rgb(250,211,211);
}
#navigator ul {
list-style-type:none;
border: 0px solid #000000;
position: absolute;
z-index: 90;
}
#navigator ul li {
width: 130px;
float: left;
border: 1px solid black;
text-align: center;
font-size: 11px;
font-weight: bold;
display: block;
}
#navigator ul li ul {
display: none;
visibility: hidden;
width: 130px;
border: 0px;
border-left: 1px solid black;
border-right: 1px solid black;
background-color: #ffffff;
margin: 1px 0px 0px -1px;
}
* html #navigator ul li ul {
margin: 0px;
background-color: #fff000;
margin: 1px 0px 0px -66px;
}
#navigator ul li ul li {
border: 0px solid black;
border-bottom: 1px solid black;
width: 130px;
}
#navigator ul ul ul {
border: 0px solid black;
border-top: 1px solid black;
border-left: 1px solid black;
border-right: 1px solid black;
float: left;
width: 130px;
margin: -18px 0px 0px 130px;
height: auto;
}
* html #navigator ul ul ul {
margin: 0px;
margin: -18px 0px 0px 65px;
}
#navigator ul li p {
margin: 0px;
padding: 3px 0px 3px 0px;
color: #000000;
width: 100%;
height: 100%;
background-color: #ff0000;
}
#navigator ul li p a {
color: #000000;
background-color: #00ff00;
}
js/menu.js
$(document).ready(function(){
$("#navigator li").hover(
function(){
$(this).children('ul:first:hidden').css({visibility: "visible",display:'block'});
},
function(){
$(this).children('ul:first:visible').css({visibility: "hidden",display:'none'});
}
);
});
Ricordatevi inoltre di includere correttamente la libreria jQuery.
Il file html non ha bisogno di spiegazioni, un semplice div che contiene un ul con degli li che a loro volta possono contenere altri ul ecc..
Il file menu.js utilizza il metodo hover di jQuery, che in pratica, mette in ascolto gli oggetti LI presenti all’interno del DIV#navigator con i metodi onmouseover e onmouseout.
Il file style.css è quello che andremo a dissezionare, vedendo passo passo i comportamenti che prende il nostro menu al variare del suo contenuto. Procederemo quindi in vari step che ci porteranno alla versione finale. Il codice in testa al file è parte del Meyerweb Reset che personalmente includo in ogni progetto.
Step 1
Il primo passo è semplice… eliminate il contenuto che segue alla definizione degli attributi per il div#navigator, otterrete questo risultato. Il contenuto degli ul li è subito visibile ed ogni elemento è a capo dell’altro. I file html e js sono rimasti invariati, infatti passando con il mouse sugli elementi LI potremo visualizzare/nascondere eventuali ul figli se disponibili.
Step 2
Non seguiremo l’ordine del codice come impostato nel file css nei vari step, infatti il file css di questo secondo passaggio sarà la versione dello step 1 con aggiunta delle definizioni di ‘#navigator ul li p’ e ‘#navigator ul li p a’. Cliccate qui per vedere il risultato e controllare se state eseguendo tutto correttamente. Abbiamo formattato i tag P ed A presenti all’interno degli LI. Perchè tag P? La versione fnale del menu senza la presenza dei tag P aveva un fastidioso difetto di sovrapposizione degli UL. Più nel dettaglio, la coordinata X dell’UL era uguale alla coordinata X del testo presente nell’LI parente sommata della sua lunghezza ( l’UL compariva subito dopo la fine del testo e non alla fine dell’LI, donando un effetto di disordine ).
Step 3
In questo passaggio le cose iniziano a prendere forma. Aggiungiamo le definizioni per ‘#navigator ul’ e ‘#navigator ul li’ ovvero l’UL che conterrà gli LI che rappresenteranno le categorie. Scrivo ‘rappresenteranno’ in quanto adesso la definizione prende tutti gli UL e gli LI discendenti del div#navigator. Ciò che abbiamo ottenuto è che adesso, le sottocategorie compaiono al di sotto della categoria a cui appartengono. Questo step 3 sarà visualizzato in maniera abbastanza differente dai vari browser ( leggi: su IE6 viene interpretato in modo differente che dagli altri browser ). Da sottolineare la presenza dell’attributo position: absolute; che permette la visualizzazione degli UL come se fossero al di fuori di qualsiasi altro elemento ( modificare questa voce con relative o rimuoverla per capire di cosa sto parlando ).
Step 4
Aggiungiamo le definizioni di ‘#navigator ul li ul’, ‘#navigator ul li ul li’ e ‘* html #navigator ul li ul’. In questo modo differenziamo la visualizzazione delle categorie di primo livello ( lo abbiamo fatto nello step 3 ) dalle sottocategorie ( a qualsiasi livello ). Inoltre definiamo che le sottocategorie di default NON debbano visualizzarsi. Della loro visualizzazione se ne occupera il file js ( che cerca il primo figlio UL nascosto dell’LI scatenante l’evento mouseover e lo visualizza ). Ciò che otteniamo è la corretta visualizzazione delle categorie di primo livello. Da notare che un selettore preceduto dal suffisso ‘* html’ viene letto esclusivamente da IE6, quindi le proprietà al suo interno sono specifiche per far funzionare il tutto anche su questo browser.
Final Step
Infine aggiungiamo le regole ‘#navigator ul ul ul’ e ‘* html #navigator ul ul ul’ che definiscono la visualizzazione per le categorie dal terzo livello in poi. Otteniamo quindi il risultato finale.
Riadattare il tutto
Ciò a cui bisogna porre attenzione modificando il css di questo menù sono principalmente la larghezza degli li/ul e la loro altezza, data principalmente dalla proprietà padding del tag P. Inoltre, la presenza del bordo di 1px è da tenere in considerazione in quanto la sua rimozione/modifica comporterebbe la modifica di altre proprietà per fare in modo che tutto si riadatti. Rispettando l’equilibrio tra le varie proprietà non dovrebbe essere eccessivamente un problema riadattare il tutto alle proprie esigenze.
Si conclude qui questo tutorial. Eventuali commenti per richieste o consigli su come modificare in meglio il codice sono sempre ben accetti.
No related posts.
Related posts brought to you by Yet Another Related Posts Plugin.












Credo che il file html sia sbagliato: ci sono dei tag p di apertura, senza chiusura, e tag a di sola chiusura.
Grazie per la segnalazione,
), testato su firefox, ie6, safari e opera, su tutti i browser il menù è visualizzato in maniera identica.
avevi perfettamente ragione, esisteva questo errore che tra l’altro ha risolto un piccolo difetto che comunque non comprometteva la qualità finale ( meglio che non ci sia però
Ciao