Creare un menu ad albero collassabile con jQuery ci permette di studiare due interessanti caratteristiche di questa libreria: il selettore :has()
e la proprietà target
dell'oggetto Event
. La prima caratteristica ci serve per sapere se una voce del menu contiene a sua volta un sottomenu, mentre la seconda ci permette di agire con sicurezza sapendo che l'elemento corrente è anche quello su cui l'evento usato ha luogo. Vediamo insieme i dettagli.
Partiamo dalla seguente struttura:
<ul id="menu">
<li>Voce 1</li>
<li>Voce 2</li>
<li>Voce 3
<ul>
<li>Voce 3.1</li>
<li>Voce 3.2</li>
</ul>
</li>
<li>Voce 4</li>
<li>Voce 5
<ul>
<li>Voce 5.1</li>
<li>Voce 5.2</li>
<li>Voce 5.3</li>
</ul>
</li>
<li>Voce 6</li>
</ul>
Definiamo degli stili CSS di base:
body {
font: 76% Verdana, sans-serif;
color: #333;
background: #fff;
margin: 2em;
}
#menu {
margin: 1em 0;
padding: 0;
list-style: none;
}
#menu li {
padding: 0 0 5px 0;
}
#menu li ul {
display: none;
}
Tutti i sottomenu sono inizialmente nascosti. A questo punto aggiungiamo due classi CSS per gestire lo stato di apertura e di chiusura di quelle voci che contengono un sottomenu:
#menu li.plus {
padding-left: 19px;
background: url(img/plus.gif) no-repeat;
position: relative;
left: -19px;
}
#menu li.minus {
padding-left: 19px;
background: url(img/minus.gif) no-repeat;
position: relative;
left: -19px;
}
Ora con jQuery dobbiamo inizialmente aggiungere la classe plus
alle voci che contengono un sottomenu:
$('li:has(ul)', '#menu').addClass('plus');
Il selettore :has()
selezionerà solo quelle voci che contengono un elemento ul
al loro interno. A questo punto dobbiamo associare un evento click
a tali voci che mostrerà il sottomenu se è nascosto o lo nasconderà se è visibile:
$('li:has(ul)', '#menu').click(function(event) {
if(this == event.target) {
if($(this).children().is(':hidden')) {
$(this).addClass('minus').children().slideDown();
} else {
$(this).removeClass('minus').children().slideUp();
}
}
}).css('cursor', 'pointer');
La classe CSS minus
viene aggiunta e rimossa a seconda se il sottomenu è nascosto (hidden) o meno. La proprietà target
dell'oggetto Event
dice a jQuery di eseguire l'azione solo sull'elemento che in quel momento è interessato dall'evento. L'azione in sè si riduce ad un effetto slideDown()
o slideUp()
sul sottomenu (mostra/nascondi).
Potete visionare l'esempio finale in questa pagina.