immagine avatar

Ciao come puoi notare ho dato una bella rinfrescatina al mio blog!
Attendo un tuo feedback, per suggerimenti e ulteriori proposte di miglioramento, ma anche, sperando che non ci siano, segnalazioni di errori o malfunzionamenti del blog. Buona lettura!

Menu verticale jQuery con effetto fisarmonica

di MaiNick | 20 Apr 2010 | jQuery | 108 Commenti
menu-verticale.jpg

UPDATE: Ho pubblicato un secondo tutorial in cui ho riportato le modifiche richieste nei feedback, come rendere la voce del menu principale anch’essa cliccabile e poter rimanere aperto il sotto menu corrispondente alla pagina visitata.

In questo tutoriale faremo un semplice menu verticale con jQuery ma che cattura l’attenzione del navigatore con l’aiuto di CSS e del plugin Easing per l’effetto a fisarmonica.

Documento HTML

Come potete vedere in seguito dalla demo, il menu è diviso in quattro voci, ciascuna definita da un elemento LI posizionati all’interno dell’elenco principale UL:

<li class="menu"> <!-- costituisce ogni sezione del menu principale -->
  <ul>
    <!-- titolo della sezione che fa aprire il sotto menu -->
    <li class="title"><a href="#">Categoria Firefox</a></li>
    <li class="sub-menu">
      <ul>
        <li><a href="http://www.mainickweb.com/hack-css-per-firefox-opera-safari-e-internet-explorer/">Articolo 1</a></li> 
        <li><a href="http://www.mainickweb.com/firefox-3-le-caratteristiche/">Articolo 2</a></li>
      </ul>
    </li>
  </ul> 
</li> 

Ogni voce del menu contiene un altro elenco UL, formato dalla voce del menu principale (li.title) e da un altro elenco UL che rappresenta il sotto menu (li.sub-menu).
All’interno dell’elemento li.title abbiamo un ancora a cui poi associamo un gestore di eventi jQuery che fa aprire il sotto menu corrispondente: il menu a discesa è nascosto di default tramite la proprietà css display: none.

Foglio di stile CSS

Con uno stile accattivante, anche la più semplice idea può fare una grande differenza nell’attenzione del visitatore.
E’ importante fare particolare attenzione che il codice CSS sia valido e che funzioni bene in tutti i browser:

li.menu {
	/* Voci dell'elenco principale */
	width: 100%;
	padding: 5px 0;
}

li.title a {
	/* Voce del menu principale */
	display: block;
	position: relative;
	width: 200px;
	height: 34px;
	padding: 10px 20px 0;
	-moz-border-radius: 5px;
	-webkit-border-radius: 5px;
	border-radius: 5px;
	background-color: #cc0000;
	color: #ffffff;
	font-family: BPreplay,Arial,Helvetica,sans-serif;
	font-size: 21px;
	overflow: hidden;
}

li.title a:hover {
	background-color: #f40000;
	text-decoration: none;
}

li.title a span {
	/* Questo span agisce come parte finale della sezione title */
	display: block;
	position: absolute;
	top: 0;
	right: 0;
	width: 4px;
	height: 44px;
}

.sub-menu {
	/* Sotto menu */
	display: none;
	width: 100%;
	padding-top: 5px;
}

.sub-menu li {
	/* Voci del sotto menu */
	margin: 5px 0;
	padding: 4px 18px;
	border: 1px solid #40392c;
	background-color: #2F2F2F;
	color: #cccccc;
}

Effetti con jQuery

In primo luogo abbiamo bisogno di includere alcuni script nel documento HTML (questo codice va messo all’interno della sezione HEAD):

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="jquery.easing.1.3.js"></script>
<script type="text/javascript" src="script.js"></script>

Per prima cosa bisogna includere la libreria jQuery (in questo caso dai server di Google), poi il plugin Easing e infine il nostro file di script.

Come potete notare dalla demo, l’effetto che si ha nell’aprire un sotto menu è simile ad un rimbalzo. Questo risultato è ottenuto con l’aiuto del plugin Easing per jQuery: esso prevede una serie di effetti interessanti.

Ecco il codice del nostro file di script:

$(document).ready(function(){

  /* Cambiare l'effetto da utilizzare */
  $.easing.def = "easeOutBounce";

  /* Associare una funzione all'evento click sul link */
  $('li.title a').click(function(e){
	
    /* Finding the drop down list that corresponds to the current section: */
    var subMenu = $(this).parent().next();
		
    /* Trovare il sotto menu che corrisponde alla voce cliccata */
    $('.sub-menu').not(subMenu).slideUp('slow');
    subMenu.stop(false,true).slideToggle('slow');
		
    /* Prevenire l'evento predefinito (che sarebbe di seguire il collegamento) */
    e.preventDefault();
  })
	
});

Per prima cosa bisogna impostare l’effetto da utilizzare (easeOutBounce), e quindi associare una funzione da compiere per l’evento click sul link in li.title: si ottiene il corrispondente sotto menu (linea ) e lo si mostra (linea ), nascondendo tutti gli altri (linea ).

Il metodo slideToggle di jQuery controlla se l’elemento è già visibile sulla pagina, e decide se mostrarlo o nasconderlo: in questo modo, quando si fa click su una sezione del menu già aperta, essa viene semplicemente chiusa.
Dopo questo, usiamo e.preventDefault() per impedire al browser di seguire il collegamento (il comportamento normale per avere cliccato su un link).

Demo Download

Tags: , , ,

108 Commenti

  1. Pierhagi ha detto:

    Ciao si c’erano degli errori di base nel codice che ti ho dato!

    Per capirci descrivo cosa vorrei che facesse il menù.

    Ad es. visualizzando la home del sito clicco su un pulsante, che x me sono le SuperCategorie, il menù si espande visualizzandomi le Categorie appartenti al pulsante cliccato rimanendo sempre nella pagina home!
    Se clicco in una Categorie, cioè in una voce nel sub-menu mi deve visualizzare la pagina con la gallery di quella categoria!

    Il mio problema è che queste azioni funzionano solo con il primo pulsante!
    Se clicco su un pulsante qualsiasi che non sia il primo non ottengo lo stesso effetto xchè questi pulsanti non ricevono il valore id x poter visualizzare l’elenco delle categorie.

    Credo che il codice js non faccia passare questi valori!

    • MaiNick ha detto:

      @Pierhagi scusami se ho capito bene vuoi che ci siano altri livelli di sotto menu SuperCategoria->Categoria->SottoCategoria. Allora bisogna modificare del tutto lo script.
      Fammi sapere e se possibile puoi postarmi il link al tuo esempio per rendermi conto meglio di quello che vuoi fare.

  2. Pierhagi ha detto:

    Ciao no non voglio una sottocategoria, guarda qui:

    http://www.fulminanti.it/categoria_accordion2.asp?id_super_categoria=29

    se tu clicchi sul primo pulsante e cioè Abbigliamento ti si apre il menù con le categorie… e così è corretto!…ma se poi decidi di cliccare su un altro pulsante non si visualizzano più le categorie!

    Ti dico già che il pulsante corretto è il “57 – Cappellini2” xchè contiene il valore dell’id_super_categoria=57 che dovrà essere utilizzato per estrarre le categorie della supercategoria Cappellini.

  3. Paolo ha detto:

    Ciao, ho cercato tra i commenti precedenti ma non ho trovato risposta.
    Non riesco a visualizzarlo in Safari, sai dirmi come mai?
    Grazie

    • MaiNick ha detto:

      Ciao @Paolo, non so perché non riesci a visualizzarlo su Safari, lo script funziona su tutti i browser puoi visualizzare la demo per verificarlo.

      • Paolo ha detto:

        Si in effetti la tua demo si vede perfettamente su Safari.
        Eppure ho solo cambiato il colore di sfondo degli item…
        veramente strano…

        • MaiNick ha detto:

          Forse modificando si verifica un errore nello script.
          Riprova ritornando allo script originale che hai scaricato e vedi se funziona, se va effettui le tue modifiche.
          Fammi sapere.

  4. Pong ha detto:

    Ciao grande plug-in , è possibile aprire il menu verso l’alto ?

    • MaiNick ha detto:

      @Pong ciao e grazie del complimento.
      vai contro corrente, comunque devi modificare il documento html menu-verticale.html della demo che puoi scaricare, spostando le voci del menu principale dopo i rispettivi sotto-menu, e modificare il file dello script javascript script.js, scusa il gioco di parole, alla riga 10 cambiare next in prev.
      Se hai problemi sono a disposizione e buon fine settimana

      • pippo ha detto:

        Si, ma è possibile aprire il menu verso l’alto spostando in alto anche le voci del menu principale? Perché con la modifica da te descritta il sotto menu compare sopra alle voci, io invece vorrei farle apparire sotto.

        PS
        menu fantastico!!!

        Grazie

    • paso ha detto:

      Fantastico e creare un sotto menu del sottomenu.. ? e possibile ho provato ma no fa niente devo solo modificare i css ?

  5. Paolo ha detto:

    Ciao, sono riuscito a risolvere il problema precedente (visualizzazione su Safari), ora abusando della tua pazienza, ti chiedo: è possibile lasciare il menu’ “aperto” durante la navigazione?
    Ovvero, se apro una categoria (nel tuo esempio i titoli rossi) e clicco su un sottomenu’, automaticamente il menu’ si richiude, costringendo l’utente ad aprirlo nuovamente per continuare a navigare.
    Puoi aiutarmi? grazie mille 🙂

  6. Stefano ha detto:

    scusami!!! ho un problema!! è possibile applicare l’apertura dei sottomenu clickando direttamente sul pulsante?? invece che sulla freccetta??? se sì come si fa?? $(document).ready(function(){

    $.easing.def = “easeOutBounce”;

    $(‘li.title’).click(function(e){

    var subMenu = $(this).parent().next();

    $(‘.sub-menu’).not(subMenu).slideUp(‘slow’);
    subMenu.stop(false,true).slideToggle(‘slow’);

    e.preventDefault();
    })

    });

    ho lasciato solo li.title > mi crea problemi non mi funziona su tutto il pulsante. sai xchè???

  7. pino ha detto:

    ciao, come è possibile creare un sottomenu del sottomenu?

    grazie

    • MaiNick ha detto:

      Ciao Pino, se vogliamo partire dalla stessa struttura realizzata nel tutorial, dobbiamo fare un paio di modifiche a tutti e tre i file che compongono l’esempio.
      Nel documento HTML dobbiamo inserire un sotto menu ad una voce di sotto menu del menu principale. Il li del sotto menu (menu di 2° livello) a cui vuoi aggiungere un “sotto sotto menu” (menu di 3° livello) deve essere sostituito con il seguente codice:

      <li>
      <ul>
      <li class="title-sub-menu"><a href="http://www.mainickweb.com/creare-un-menu-a-lista-in-ordine-alfabetico-con-jquery/">Articolo 1</a></li>
      <li class="sub-sub-menu">
      <ul>
      <li><a href="http://www.mainickweb.com/">Sotto sotto menu - voce 1</a></li>
      <li><a href="http://www.mainickweb.com/">Sotto sotto menu - voce 2</a></li>
      </ul>
      </li>
      </ul>
      </li>

      Nel foglio di stile CSS aggiungiamo altre due regole:

      .sub-sub-menu {
      /* Sotto menu */
      display: none;
      width: 100%;
      padding-top: 5px;
      }

      .sub-sub-menu li {
      /* Voci del sotto menu */
      margin: 5px 0;
      padding: 4px 18px;
      border: 1px solid #40392c;
      background-color: #2F2F2F;
      color: #cccccc;
      }

      con le quali applichiamo lo stesso stile del sotto menu di 2° livello al sotto menu di 3° livello. Per ridurre le righe di codice possiamo aggiungere il selettore del sotto menu di 3° livello alle regole indicate per il sotto menu di 2° livello.
      Infine il file javascript va aggiunto lo script per determinare la stessa funzionalità del sotto menu di 2° livello al nuovo sotto menu di livello inferiore:

      /* Associare una funzione all'evento click sul link */
      $('li.title-sub-menu > a').click(function(e){

      /* Finding the drop down list that corresponds to the current section: */
      var subMenu = $(this).parent().next();

      /* Trovare il sotto menu che corrisponde alla voce cliccata */
      $('.sub-sub-menu').not(subMenu).slideUp('slow');
      subMenu.stop(false,true).slideToggle('slow');

      /* Prevenire l'evento predefinito (che sarebbe di seguire il collegamento) */
      e.preventDefault();
      });

      come puoi notare il codice è uguale, cambiano solo i selettori.

      • pino ha detto:

        Mai, davvero non so come ringraziarti!

        • MaiNick ha detto:

          Di niente è un piacere aiutare i miei lettori.

          • fabiana ha detto:

            Ciao Nick, anzituuto grazie per il bellissimo Tutorial.
            Vorrei aggiungere alle voci del submenu altri sub menu.
            ho visto che hai già dato la soluzione a Pino nell’altra versione del tutorial, ti scrivo da qui perchè io ho utilizzato questa e no riesco a farla funzionare.

            Ho aggiunto come dici tu le regole al foglio di stile CSS:
            .sub-sub-menu {
            /* Sotto menu */
            display: none;
            width: 100%;
            padding-top: 5px;
            }

            .sub-sub-menu li {
            /* Voci del sotto menu */
            margin: 5px 0;
            padding: 4px 18px;
            border: 1px solid #40392c;
            background-color: #2F2F2F;
            color: #cccccc;
            }

            Ho aggiunto aggiunto lo script al file javascript :

            /* Associare una funzione all’evento click sul link */
            $(‘li.title-sub-menu > a’).click(function(e){

            /* Finding the drop down list that corresponds to the current section: */
            var subMenu = $(this).parent().next();

            /* Trovare il sotto menu che corrisponde alla voce cliccata */
            $(‘.sub-sub-menu’).not(subMenu).slideUp(‘slow’);
            subMenu.stop(false,true).slideToggle(‘slow’);

            /* Prevenire l’evento predefinito (che sarebbe di seguire il collegamento) */
            e.preventDefault();
            });

            é nel documento HTML che penso di sbagliare, ti scrivo il mio:

            AIR

            AG-92
            FAS 6004

            mi piacerebbe che al click degli articoli AG-92 e Fas 6004 si aprissero altri articoli, puoi aiutarmi?
            Ti ringrazio anticipatamente
            fabiana

          • fabiana ha detto:

            scusa riprova a mettre il mio html

            AIR

            AG-92
            FAS 6004

          • fabiana ha detto:

            Ciao Nick, scusa, ma come mai non prende il mio codice html?

  8. lorenzo ha detto:

    Ciao!!! scusa la domanda banale. ma non riesco a far funzionare solo il link sulla voce principale. Nei sottomenù funziona ma se volessi mettere una voce solo con il link senza sottomenù non riesco a far funzionare il link. dove sbaglio?

    • MaiNick ha detto:

      Ciao, se ho capito bene vuoi il menù spiegato nel tutorial senza che abbia il sottomenu. Devi cancellare il blocco di codice HTML <li class="sub-menu"> e non aggiungere alla pagina lo script javascript.

      • lorenzo ha detto:

        Io vorrei fare una cosa tipo questa:

        torna a google

        senza sottomenù ma che cliccando sopra invece di espandersi vada al link.si può fare?

        • MaiNick ha detto:

          Ok avevo capito bene, puoi seguire quello che ti ho scritto sopra.

          • lorenzo ha detto:

            Ciao! si però io volevo che solo quello non fosse con il sotto menù.. mentre le altre voci si…è possibile?

          • MaiNick ha detto:

            Ok, allora aggiungi lo script JavaScript alla pagina e modificalo aggiungendo dopo la riga $('li.title a').click(function(e){ un IF che contiene tutto il codice if ( $(this).parent().next().hasClass('sub-menu') ) {

          • lorenzo ha detto:

            ciao!!! grazie per la pazienza!!! allora ora funziona ma non espande le altre voci. il codice è venuto così:

            $(‘li.title a’).click(function(e){
            if ( $(this).parent().next().hasClass(‘.sub-menu’) ) {
            /* Finding the drop down list that corresponds to the current section: */
            var subMenu = $(this).parent().next();

            /* Trovare il sotto menu che corrisponde alla voce cliccata */
            $(‘.sub-menu’).not(subMenu).slideUp(‘slow’);
            subMenu.stop(false,true).slideToggle(‘slow’);

            /* Prevenire l’evento predefinito (che sarebbe di seguire il collegamento) */
            e.preventDefault();}
            })

            dove ho sbagliato? alla riga aggiunta da te ho solo aggiunto un . alla sub-menu perchè prima non funzionava. questo che ti ho postato funzion ma non espande gli altri.
            grazie mille

          • MaiNick ha detto:

            In realtà è corretto non mettere il punto perché già stai indicando l’attributo class, comunque va bene anche con il punto.
            Ho modificato i file e ho messo come esempio la prima voce che punta al sito Google, puoi scaricare i file da questo link.

          • lorenzo ha detto:

            Perfetto!!! grazie mille…

  9. siti web cilento ha detto:

    Lo stile non è bellissimo ma almeno è modificabile… il menu funziona bene!!!

  10. Gabriella ha detto:

    ciao! innanzitutto complimenti, ho trovato il menu molto utile..!! vorrei però chiederti due cose:
    1) se volessi eliminare l’effetto rimbalzo una volta che il menù scende per intenderci, come devo fare?
    2) come faccio ad inserire il tuo pacchetto (jquery e foglio di stile) dentro un sito già iniziato? perchè riesco a vederlo e modificarlo ma non so come inserirlo dentro al mio sito che ho già iniziato a fare…(con dw)
    scusa le domande magari banali ma sono agli inizi..

    grazie!

    • MaiNick ha detto:

      Grazie Gabriella. Per inserire il menu nel tuo sito web devi copiare la parte del foglio di stile relativa al solo menu dalla riga 19 alla riga 82, collegare i javascript di jQuery e il file script.js e infine copiare dalla pagina html tutto la parte in riferimento all’elenco ul e, ovviamente, cambiare le voci di menu con i relativi link.
      Per eliminare l’effetto non è necessario collegare alla pagina html il file jquery.easing.1.3.js ed eliminare la riga 4 dal javascript script.js

  11. Giovanni ha detto:

    Ciao,
    complimenti è troppo bello questo menu volevo solo chiederti come faccio a modificare lo script per fare in modo che quando apro il sottomenu e vado sulla pagina collegata mi rimane aperto il sottmenu ?
    ne ho assolutamente bisogno grazie mille
    grazie

  12. Gabriella ha detto:

    Scusa posso avere una risposta anche io? 😉 saresti gentilissimo.. sto preparando un esame e mi servirebbe

    Grazie!

  13. Sebastiano ha detto:

    Ciao ti voglio chiedere come faccio a cambiare i colori delle voci (Articolo 1 ecc)

  14. Dave ha detto:

    Ciao davvero ottimo devo dire..:) Però ho un problema. Ho provato a inserire un sotto menu a un sotto menu… Fin li ok, solo che una volta che apro il secondo sotto menu, la tendina con il sotto menu mi viene chiusa, e quando provo a riaprirla il menu si apre senza problemi.. Hai qualche idea?

  15. Franco ha detto:

    Bellissimo script, volevo chiederti come poter fare in modo che se una persona clicca al di fuori del menu il menu scompaia?

  16. Flo ha detto:

    ciao, ho trovato questo bellissimo menu e provo a fare un po di prove a modificarlo su alcuni aspetti … tolto il rimbalzo che cera sono riuscito a fare pure il passo di usare un pulsante come semplice pulsante e non per aprire un sotto menu … il mio problema e questo pero … vorrei che il pulsante che apre il sotto menu possa essere usato a suo tempo come pulsante proprio .. cioe quando cliko su google che si apra il sotto menu come ora per altre 3 pagini ma allo stesso momento che mi porti alla pagina google ad sempio con delle info principale … come posso risolvere questo problema? grazie per il tuo aiuto

  17. Pasquale ha detto:

    Ciao
    pensavo di utilizzare il tuo script nel mio sito. L’ho provato in locale e mi piace molto.
    Volevo chiederti una cosa: quando si seleziona un link principale dopo che vengono visualizzati i link contenuti mi piacerebbe che il link principale rimanesse evidenziato di un determinato colore in modo da far capire in quale voce siamo. E’ possibile ?. se si puoi dirmi come si fa ?.
    Grazie.

Trackbacks

  1. Anonimo ha detto:

    […] […]

Lascia un Commento

^ Torna su