jQuery: menu ad albero collassabile

jQuery: menu ad albero collassabile

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.

Torna su