accordion menu con jQuery

December 5th, 2007

Con estrema lentezza visti i vari impegni - scusa Nicola - sto lavorando ad un progetto freelance; per le tematiche relative all’interaction design ho pensato di usare jQuery mentre il markup è rigorosamente sviluppato in xHTML strict; il tempo non è molto e mi son detto: voglio usare quanti più plugin riesco, voglio vedere quanto è vero stò motto “write less, do more”, e quanto riesco a customizzarli in base alle mie esigenze.

Ma veniamo al perchè di questo post: nel mentre sviluppavo il mio design già pensavo ad un simpatico menu di tipo “a soffietto” o accordion, per dirla in inglese, che suona meglio.
Ed ho deciso di condividere con voi tale idea anticipandovi che comunque ci sono già buoni tutorial e plugin sull’argomento ma nessuno, non capisco perchè, parte da un set di liste non-ordinate annidate.
Questo è il nostro markup: molto semplice. Ricordiamoci di dare un ID alla lista.


<ul id="prjcats">
<li><a href="#">Henseleit Helicopters</a>
<ul>
<li><a href="#">MP V91 XL</a></li>
<li><a href="#">MP XLE</a></li>
</ul>
</li>
<li><a href="#">Mikado Model Helicopters</a>
<ul>
<li><a href="#">V Stabi 3 Axis</a></li>
<li><a href="#">Logo 500DX</a></li>
<li><a href="#">Logo 500 3D</a></li>
</ul>
</li>
<li><a href="#">Thunder Tiger</a>
<ul>
<li><a href="#">A109 Scale Fuselage Kit</a></li>
<!-- eccetera -->
</ul>
</li>
</ul>

Ora passiamo allo script che ce la trasforma in un accordion menu con effetto easing.


<script type="text/javascript">
$(function(){
$("ul#prjcats li ul").hide();
$("ul#prjcats>li>a").click(function() {
$(this).addClass("current");
var $subnav = $(this).next();
if($subnav.is(":visible")) {
$subnav.animate({height: "toggle"}, 750, "easeInOutExpo").prev().removeClass("current");
}
if(!$subnav.is(":visible")) {
$("ul#prjcats li ul:visible").animate({height: "toggle"}, 750, "easeInOutExpo").prev().removeClass("current");
$subnav.animate({height: "toggle"}, 750, "easeInOutExpo");
}
return false;
});
});
</script>

E questo è il nostro script jQuery. Ricordiamoci di includere il framework stesso e il plugin jquery.easing


<script type="text/javascript" src="http://www.gcmingati.net/wordpress/wp-content/themes/giancarlo-mingati/js/jquery-1.2.1.min.js"></script>
<script type="text/javascript" src="http://www.gcmingati.net/wordpress/wp-content/themes/giancarlo-mingati/js/jquery.easing.1.2.js"></script>

Ora vediamo nello specifico cosa fà questo script:
Per prima cosa nascondiamo tutte le liste annidate.


$("ul#prjcats li ul").hide();

Al click dei link di primo livello - notare la sintassi “>”


$("ul#prjcats>li>a").click(function()

aggiungiamo una classe .current (il colore rosso di selezione) e assegnamo alla variabile $subnav le liste di secondo livello.
.next() trova il primo elemento “discendente” di A: appunto una lista UL


$(this).addClass("current");
var $subnav = $(this).next();

Qui controlliamo se $subnav è visibile - cioè aperto; se lo è usiamo toggle per switchare tra lo stato di visibile o invisibile. Se é “.is” visibile, chiudi la sub-lista.
Per l’animazione usiamo un tempo “750″- millesimi - ed un metodo easing “easeInOutExpo”. Risaliamo con .prev() ad A e gli togliamo la classe di selezione.
Nota sugli effetti easing: sono 30 e potete giocherellare con i vari metodi di cui trovate un elenco qui. Provate l’effetto che più vi piace. E un’ulteriore nota: gli effetti si fanno apprezzare su liste con molti elementi; se le vostre liste sono corte, evitate effetti di accelerazione/rimbalzo.


if($subnav.is(":visible")) {
$subnav.animate({height: "toggle"}, 750, "easeInOutExpo").prev().removeClass("current");
}

Qui invece controlliamo se $subnav selezionato non è visibile - è chiuso - e se lo è, prima controlliamo se qualcun altro è aperto “"ul#prjcats li ul:visible"” e lo chiudiamo, e poi apriamo il $subnav selezionato.


if(!$subnav.is(":visible")) {
$("ul#prjcats li ul:visible").animate({height: "toggle"}, 750, "easeInOutExpo").prev().removeClass("current");
$subnav.animate({height: "toggle"}, 750, "easeInOutExpo");
}

Dopo gli if, usiamo “return false;” per evitare che al click dei link di primo livello, che sono vuoti “#”, si verifichi il balzo verso l’alto della pagina.


return false;

Ed ecco fatto, accordion menu con effetto easing.