Uno degli effetti più utili e gradevoli da implementare su un sito sono i menu a cascata (drop-down menu in inglese). Siamo abituati a vedere menu a cascata ovunque, e la maggior parte dei linguaggi di programmazione permette di crearli e gestirli con poche istruzioni. Per quanto possa sembrare strano, questo non vale per l'HTML: sebbene ogni sito che si rispetti utilizzi qualche effetto grafico a cascata (o a scomparsa), dietro le quinte c'è spesso qualcuno che si è ingegnato per realizzarlo.
Oggi vedremo come implementare un menu a cascata con poche righe, utilizzando jQuery.
Teoria
La prima caratteristica di un menu a cascata è il timing, ovvero la necessità di rallentare l'apparizione del menu, per creare un piacevole effetto di comparsa e scomparsa (fadein e fadeout). Abbiamo già visto che gestire il delay in JavaScript non è affatto intuivo. Siccome jQuery è una libreria JavaScript, valgono esattamente le stesse limitazioni: non possiamo sfruttare un ciclo per eseguire le istruzione una di seguito all'altra, con tempi diversi, perché il browser le eseguirebbe sempre e comunque tutte assieme, alla fine del ciclo.
Un modo di aggirare il problema è usare la concatenazione di metodi diversi con la dot notation, ovvero
fai_questo(100).fai_quello() ;
Se il metodo fai_questo()
prevede un certo ritardo nell'esecuzione, supponiamo di 100 ms (come scritto qui sopra), allora saremo sicuri che il metodo fai_quello()
verrà eseguito in ritardo rispetto al primo (in questo caso dopo circa 100 ms). La tecnica si potrebbe applicare per creare effetti di scomparsa mediante le funzioni fadeOut()
e fadeIn()
di jQuery, ad esempio
$('#mio_menu').fadeOut(500).fadeIn(500) ;
la riga qui sopra non serve a nulla ma "funziona", perché fa scomparire l'elemento mio_menu
in mezzo secondo, e dopo un altro mezzo secondo lo fa riapparire. Far scomparire e apparire subito dopo un elemento è abbastanza inutile, però dimostra che la tecnica funziona, perché ci permette di eseguire le funzioni con il timing previsto. A questo punto potremo illuderci di scrivere un codice del genere
$('#menu_1').fadeOut(500).$('#menu_2').fadeOut(500) ;
ma questo non gira nemmeno! La dot notation permette di eseguire metodi solo sullo stesso oggetto, o per la precisione: sull'oggetto ritornato dal metodo precedente. Quindi non ha alcun senso applicare il metodo
$('#menu_2')
sull'oggetto
$('#menu_1').fadeOut(500)
La morale è che jQuery non permette di gestire il delay in modo diverso da JavaScript, ed è giusto che sia così: JavaScript sta “sotto” a jQuery, i limiti strutturali della libreria dipendono dalle fondamenta su cui è edificata, e non viceversa!
La soluzione corretta è quella di sfruttare quando già imparato nella gestione del delay in JavaScript e applicarlo alla funzioni di jQuery, ottenendo un gradevole effetto a scomparsa con poche righe. Passiamo quindi alla pratica.
Pratica
Consideriamo per semplicità un menu HTML realizzato con una tabella
<table>
<tr><td><a href="#" onclick="collapse(11,13);">Home</a></td></tr>
<tr id="row_11"><td><a href="#">Software</a></td></tr>
<tr id="row_12"><td><a href="#">Formazione</a></td></tr>
<tr id="row_13"><td><a href="#">Links</a></td></tr>
</table>
Immaginando di avere altre righe più sotto, del tipo row_21, row_22, row_23 ecc...
Useremo poi la funzione JavaScript
function collapse(n, tot) {
var t = 100 ;
menu_div = $('#' + 'row_' + n) ;
if (menu_div.is(":visible") ) {
for (i = n ; i <= tot ; i++)
$('#row_' + i).fadeOut ( t*(i-n) ) ;
} else {
for (i = n ; i <= tot ; i++)
$('#row_' + i).fadeIn ( 3*t*(i-n) ) ;
}
};
Ecco finalmente un menu a cascata funzionante! Abbiamo aggirato il problema del delay assegnando tempi diversi alle diverse righe della tabella. Durante il fadeOut()
la prima riga avrà delay = 0
, la seconda delay = 100
, la terza delay = 200
. Vale lo stesso discorso per il fadeIn()
, a parte il fattore 3 che abbiamo aggiunto per rallentare la comparsa del menu: spesso è più piacevole vedere scomparire quasi subito ciò che non serve, e veder apparire un po' più lentamente (ma non troppo) ciò che si serve.