Semplice menu a tendina dropdown con jQuery

Di Davide De Maestri - gleenk  //  Archivio Articoli, CSS, jQuery  //  21 Commenti

Realizzare in jQuery un menù a tendina semplice, cross-browser, ad un solo livello di profondità, richiede veramente poco tempo e conoscenze tecniche minime. Useremo infatti due funzioni semplicissime, ovvero: slideUp() e slideDown(). L’unico vero “ostacolo” di sempre è la resa gradevole su tutti i browser, soprattutto su IE6.

Il markup html

Il codice html che utilizziamo sarà molto semplice, useremo infatti delle semplici liste per creare le nostre voci di menù. Prepariamo già alcune voci con le classi first e last, che ci permettono, via css, di attribuire ad esse alcune proprietà grafiche distintive.

<ul id="nav">
	<li class="first"><a href="#">Voce 01</a></li>
	<li><a class="selected" href="#">Voce 02</a>
<ul>
	<li><a href="#">Sottovoce Menu Numero 01</a></li>
	<li><a href="#">Sottovoce Menu Numero 02</a></li>
	<li class="last"><a href="#">Sottovoce Menu Numero 03</a></li>
</ul>
</li>
	<li><a href="#">Voce 03</a>
<ul>
	<li><a href="#">Sottovoce Menu Numero 04</a></li>
	<li><a href="#">Sottovoce Menu Numero 05</a></li>
	<li><a href="#">Sottovoce Menu Numero 06</a></li>
	<li class="last"><a href="#">Sottovoce Menu Numero 07</a></li>
</ul>
</li>
	<li class="last"><a href="#">Voce 04</a></li>
</ul>

Il css del menù

Del codice CSS che utilizziamo è bene sottolineare:

  • Utilizzo della proprietà block sui link in modo che prendano la larghezza dei li in cui sono contenuti
  • Trasformazione dei <li> in elementi di blocco con float:left
  • Utilizzo di CSS3 per arrotondare i bordi (border-radius) e di transizioni al passaggio del mouse (webkit-transition)
  • Mini-fix per IE6 (meglio includerlo in un foglio stile separato!)

Per il resto si tratta di decorazioni grafiche adattabili ai propri gusti!

body {
	font-family:arial;
	font-size:11px;
	}
 
#nav {
	margin:0;
	padding:0;
	list-style:none;
}	
 
#nav li {
	float:left;
	display:block;
	width:100px;
	background:#E0E0E0;
	position:relative;
	z-index:500;
	margin:0 1px;
	-webkit-transition: all 0.1s ease-in-out;
        -moz-transition: all 0.1s ease-in-out;
        -ms-transition: all 0.1s ease-in-out;
        -o-transition: all 0.1s ease-in-out;
        transition: all 0.1s ease-in-out;
}
#nav li.first {
        -moz-border-radius:5px 0 0 5px;
        -webkit-border-radius:5px 0 0 5px;
	border-radius:5px 0 0 5px;
	}
#nav li.last {
        -webkit-border-radius:0 5px 5px 0;
	-moz-border-radius:0 5px 5px 0;
        border-radius:0 5px 5px 0;
	}
#nav li li.last {
        -webkit-border-radius:0 0 5px 5px;
	-moz-border-radius:0 0 5px 5px;
        border-radius:0 0 5px 5px;
	}
#nav li a {
	display:block;
	padding:8px 5px 0 5px;
	font-weight:700;
	height:23px;
	text-decoration:none;
	text-align:center;
	color:#333;
}
#nav li a:hover {
	color:#C00;
}
#nav li li:hover {
	-webkit-transform: translate(+10px,0);
	}
#nav a.selected {
	color:#C00;
}
#nav ul {
	position:absolute;
	left:0;
	display:none;
	margin:0 0 0 -1px;
	padding:0;
	list-style:none;
}
#nav ul li {
	width:100px;
	float:left;
	border-top:1px solid #fff;
}
#nav ul a {
	display:block;
	height:auto;
	padding: 8px 5px;
	color:#666;
}
/* fix ie6, meglio inserirlo in un file .css separato */
*html #nav ul {
	margin:0 0 0 -2px;
}

Il codice jQuery per animare l’effetto di discesa a tendina

Come anticipato in precedenza, il codice jQuery da utilizzare per rendere l’effetto desiderato sarà molto semplice:

$(document).ready(function () {
      $('#nav li').hover(
		function () {
			//mostra sottomenu
			$('ul', this).stop(true, true).delay(50).slideDown(100);
 
		}, 
		function () {
			//nascondi sottomenu
			$('ul', this).stop(true, true).slideUp(200);		
		}
	);
});

Come vedete le funzioni slideUp() e slideDown() sono situate all’interno della funzione hover(). Questo perchè questa funzione permette di considerare, all’interno di essa, due stati: uno stato di mouseover ed un secondo stato di mouseout. Quindi, quello che farà nel nostro caso sarà di:

  • Far scendere la tendina al mouseover del <li> su cui sto passando, che contiene le sottovoci
  • Far risalire la tendina al mouseout (quando il mouse esce dall’elemento lista)

100 è il tempo, espresso in millisecondi, in cui avviene la transizione. La funzione .stop() invece impedisce di eseguire a ripetizione l’azione e, con il trick della funzione delay() andiamo ad impedire che un passaggio troppo veloce sulla voce di menù causi l’effetto di rimbalzo!
Semplice no?

Altri articoli che potrebbero interessarti

  1. Un semplice menù a tendina con Jquery
  2. Realizzare una semplice gallery di immagini con jQuery
  3. Accordion semplice e cross-browser
  4. Border Radius CSS3 – Come arrotondare i bordi
  5. Lo pseudo selettore :target | CSS3
Webdesign Feed Rss
  • Ser Serpico

    Veramente… ma vermanete bello! complimenti!” solo non riesco a farlo funzionare!!!!!
    ma fatemi capire funziona anche in estensione asp!?!? vi spiego sto provando anche con estensione .htm ma niente non mi funziona mi dice sempre che cìè un errore alla seguente riga:
    $(document).ready( function(){
    come lo risolvo?!?!? ho anche copiato pari parui l’esempio della demo… ma niente!

    • http://www.gleenk.com/ Davide De Maestri

      Ciao, se stai usando un cms potrebbe essere necessario utilizzare la sintassi jQuery(function(){
      });
      invece del $ dal momento che causa conflitto con altre librerie javascript. Inoltre, banale ma bene precisarlo, assicurati di aver caricato correttamente jQuery.

  • Gipsyone

    Tutto chiaro… Però perchè non dici dove mettere i cl codice?

  • Ppiero74

    Ciao, complimenti il tutto è molto semplice e ben spiegato :)
    Volevo sapere se era possibile inserire altre voci come sottomenù e se si come posso fare?
    Cioè ad esempio Menù1 –> Sottomenù 1 –> Sottomenù di Sottomenù 1 e così via.
    Grazie in anticipo

    • http://www.gleenk.com/ Davide De Maestri

      Ciao, si possono inserire altre voci ma occorre ampliare lo script. Sostanzialmente per fare un terzo livello dovresti posizionarlo in modo assoluto via css e spostarlo a sinistra a seconda della larghezza del che lo contiene con jQuery calcolandola dinamicamente (usando width())

  • luke

    Ciao! è passato un annetto ormai dalla pubblicazione di questa guida.. quindi sono cambiati alcuni script..
    ora risulta incompatibile con mozilla ed explorer..sai come risolvere?
    grazie

    • http://www.gleenk.com/ Davide De Maestri

      Ciao, ho appena controllato la demo che trovi qui sopra e funziona correttamente su tutti i browser recenti, sei sicuro di aver fatto tutto correttamente? :)

      • luke

        Grazie della risposta celere!
        Si ho fatto tutto bene.. per essere sicuro ho proprio guardato la demo su mozilla.
        La tendina scende benissimo ma quando mi sposto su un sotto menù questo non si sposta a destra di quei 10px ma rimane fisso come se non leggesse il comando.
        Succede su mozilla ed explorer! Su chrome e safari invece è perfetto.Invece, questo errore mio probabilmente, quando esco dalla tendina da destra sinistra o sotto (quindi quando un sottomenù è spostato di 10 px) la tendina torna su a scatti. puoi illuminarmi?
        gentilissimo :)

        • http://www.gleenk.com/ Davide De Maestri

          Ciao! Non avevo capito! Il punto in questione è questo: -webkit-transform: translate(+10px,0);
          Aggiungi gli altri prefissi proprietari e la proprietà senza prefisso e dovrebbe funzionare per i browser che lo supportano ;)

        • luke

          Giusto!!! non ci avevo pensato che webkit fosse riferito a chrome!!! Grazie mille!!
          e invece sai da cosa può dipendere lo scatto? quello succede a me non alla demo.. ti incollo il codice in txt:
          http://www.2shared.com/document/zr4goTzt/tend.html
          Grazie mille!
          p.s. lo uso in coppia con lazyload ma non credo sia quello il problema!

        • http://www.gleenk.com/ Davide De Maestri

          Se hai un link gli do un’occhiata rapida, non ho il tempo di scaricare il txt ecc :) grazie!

        • Anonimo

          http://www.johnnyrao.it/public/galleria2.html 
          Qua puoi vedere lo scatto della tendina quando torna indietro (ho constatato che lo fa solo su chrome)
          Inoltre li c’è un problema che non so risolvere. quando clicco su un immagine della galleria il menù non viene coperto dal popup o.o

        • luke

          Scusami… non so come editare!

          Ho aperto il codice che ti ho mandato (aggiungendo il caricamento degli script) in html su chrome e li inrealtà non scatta quindi credo che non riesca a convivere bene con lazy load… o magari lo implemento male io… cosa faccio?? XD
          se vuoi contattarmi in privato :) ti ringrazio

  • Lillo_95

    Come posso fare ad inserire lo script jQuery? non riesco a capire scusate :) Grazie

    • Anonimo

      Ciao, guarda il codice sorgente della demo, dovresti capire come fare :)

  • Aaeru88

    Hei ciao!:)
    Molto bello come menu a tendina..ma potresti spiegarmi dove devo mettere i seguenti codici??Uso blogspot..grazie!

    • Anonimo

      Ciao! Premetto che non conosco blogspot, tuttavia mi risulta che sia possibile inserire dell’html nelle varie sezioni. Quello che dovresti fare è (se non è già inserito di default) aggiungere nell’head il richiamo alle librerie jQuery

      e poi aggiungere, sempre nell’head, lo script che ho postato con il relativo css.

  • Giacomo

    Ciao Gleen! Grazie per il tutorial, è proprio ben fatto! C’è una cosa che in effetti non mi è chiara nella parte di jQuery: non ho mai visto un metoco costruito con $(‘ul’, this).slideUp, cioè con l’elemento a cui applico il metodo seguito da una virgola e this. Sai darmi una mano? Grazie!

    • gleenk

      Ciao Giacomo, ti dirò, anche io era la prima volta che lo vedevo, tuttavia semplicemente mostra l’ul discendente del li su cui vai in mouseover. Ad ogni modo concordo sul fatto che altre sintassi siano più chiare, è bello sperimentare però ogni tanto :)

    • Giacomo

      mmmh, in effetti $(‘ul’, this).slideUp potrebbe essere uno shorthand per $(this).find(‘ul’). buono a sapersi. ciao!

      • Anonimo

        Esatto, proprio così ;)

Davide De Maestri - DMSDVD86L27F704W

Privacy Policy