Questo sito utilizza i cookie per personalizzare i contenuti e gli annunci (Google AdSense), fornire le funzioni dei social media (condivisione degli articoli) e analizzare il traffico (Google Analytics). Inoltre fornisce informazioni sul modo in cui utilizzi il sito alle agenzie pubblicitarie, agli istituti che eseguono analisi dei dati web e ai social media miei partner (Google). Il proseguimento nella navigazione implica un tacito assenso all'utilizzo dei cookies. Se non sei d'accordo sull'utilizzo, ti invito ad allontanarti da questo sito. Visualizza i dettagli.

Domenica 4 Dicembre 2016

Valutazione attuale: 4 / 5

Stella attivaStella attivaStella attivaStella attivaStella inattiva
 
 Sample ImageVolete inserire nelle vostre pagine un menù ad albero? Niente di più semplice!
Scartate a priori tutti gli applet java, i componenti flash e chi più ne ha più ne metta, vi bastano poche righe di codice e qualche semplicissima funzione javascript, ed il gioco è fatto!
Per prima cosa direi di affrontare il discorso della creazione del menù vero e proprio.
La cosa forse più complessa di tutti i menù ad albero che ho visto finora risiede certamente nella creazione grafica di tali menù.
Se non vogliamo adottare applett java o oggetti in flash la via più logica risulta quella di gestire la creazione del menù utilizzando i layers.
Ragazzi, credetemi se vi dico che ci ho perso veramente dei giorni di lavoro in passato per gestirmi correttamente tutti i layer, la loro creazione dinamica, il posizionamento ancorato e dinamico anch'esso, la visualizzazione e l'ordine di sovrapposizione con gli altri layer e gli altri oggetti all'interno della pagina.
Una gran seccatura!

Ma allora come risolvere?!?!?

Fortunatamente l'HTML nudo e crudo ci fornisce una soluzione!

Avete visto com'è strutturato un menù ad albero?

Non ricorda molto un elenco puntato?

Si, si! Proprio un elenco tipo:

      Voce 1
        riga 1 voce 1
        riga 2 voce 1
        ......
        riga N voce 1
        Sotto-Voce voce 1
            riga 1 sotto-voce 1
            riga 2 sotto-voce 1
            ...
            riga N sotto-voce 1
       

    Voce 2

        riga 1 voce 2
        riga 2 voce 2
        ......
        riga N voce 2


Allora perchè non usare questa struttura che l'HTML ci mette a disposizione, liberandoci così dell'80% del lavoro?
Il menù dell'esempio diventa:

 <ul>
        <li><a href="#">Voce 1</a>
            <ul>
                <li><a href=
"#">riga 1 voce 1</a></li>
                <li><a href=
"#">riga 2 voce 1</a></li>
                <li><a href=
"#">....</a></li>
                <li><a href=
"#">riga N voce 1</a></li>
                <li><a href=
"#">Sotto-Voce voce 1</a>
                    <ul>
                        <li><a href=
"#">riga 1 sotto-voce 1</a></li>
                        <li><a href=
"#">riga 2 sotto-voce 1</a></li>
                        <li><a href=
"#">...</a></li>
                        <li><a href=
"#">riga N sotto-voce 1</a></li>
                    </ul>
                </li>
            </ul>
        </li>
        <li><a href=
"#">Voce 2</a>
            <ul>
                <li><a href=
"#">riga 1 voce 2</a></li>
                <li><a href=
"#">riga 2 voce 2</a></li>
                <li><a href=
"#">...</a></li>
                <li><a href=
"#">riga N voce 2</a></li>
            </ul>
        </li>
    </ul>

   

In pratica tutto il menù è contenuto nei TAG UL. Ogni voce poi è composta da un costrutto di tag LI per il nome e UL che contiene i tag LI degli elementi del menù.
Ogni menù può avere più sottomenù annidati a qualsiasi profondità.

Ricapitolando la struttura del menù è

    <UL> definisce l'intero menù
        <LI> definisce la prima voce del menù
            <UL> raggruppa gli elementi della prima voce del menù
                <LI></LI> rappresenta una voce del menu
            </UL> chiude il raggruppamento  degli elementi della prima voce del menù
        </LI> chiude la prima voce del menù
    </UL> chiude l'intero menu




Bene, a questo punto abbiamo ottenuto un menù ad albero totalmente espanso e che non è possibile gestire. Si tratta ancora di un elenco puntato e non di un menù. Per trasformarlo in menù occorre fare ancora qualche operazione.
Per prima cosa vediamo di inserire le immagini. Non esiste menù ad albero senza le icone delle cartelle e dei file. Vediamo ora come impostare, grazie agli sili, le immagini.

Negli header html andiamo ad inserire il codice di stile:
 
    <style type="text/css">
        <!--
        body     {
                font: .80em verdana, helvetica, sans-serif;   
            }

        ul     {
                list-style: disc url(document.png);
                margin:0;padding:0 2em;
            }

        li.Menu {
                list-style: square url(closedfolder.png);
            }
        -->
    </style>



Dove
    in body specifichiamo il font che vogliamo usare nel menù e la sua dimensione
    in ul diciamo che il puntatore da utilizzare è l'immagine doc.gif
    in li.Menu diciamo che il puntatore da utilizzare è l'immagine closedfolder.png

Assegniamo ora le classi agli elementi HTML

    <ul>
        <li class="Menu"><a href="#">Voce 1</a>
            <ul>
                <li><a href="#">riga 1 voce 1</a></li>
                <li><a href="#">riga 2 voce 1</a></li>
                <li><a href="#">....</a></li>
                <li><a href="#">riga N voce 1</a></li>
                <li class="Menu"><a href="#">Sotto-Voce 1</a>
                    <ul>
                        <li><a href="#">riga 1 sotto-voce 1</a></li>
                        <li><a href="#">riga 2 sotto-voce 1</a></li>
                        <li><a href="#">...</a></li>
                        <li><a href="#">riga N sotto-voce 1</a></li>
                    </ul>
                </li>
            </ul>
        </li>
        <li class="Menu"><a href="#">Voce 2</a>
            <ul>
                <li><a href="#">riga 1 voce 2</a></li>
                <li><a href="#">riga 2 voce 2</a></li>
                <li><a href="#">...</a></li>
                <li><a href="#">riga N voce 2</a></li>
            </ul>
        </li>
    </ul>


Fatto? BRAAAAAVI (scusatemi, un attacco d'arte! :-).. ok, piccolo omaggio ad un VERO eroe: Giovanni Muchacha !)     Sample Image
 

A questo punto dovremmo essere in grado di visualizzare a fianco di ogni LI l'icona del documento, tranne che per i LI che hanno la classe Menu, lì vedremo l'icona di una cartella chiusa.

Bene, cominciamo a dare un po' di movimento a questo menu!
Forse non tutti sanno che esiste una proprietà dell'oggetto UL, la proprietà display dello style. Questa proprietà può essere "block" o "none" a seconda se vogliamo nascondere o visualizzare gli elementi in esso contenuti.
Avvaliamoci di questa proprietà per creare una funzione che nasconda o mostri il contenuto dell'oggetto UL che contiene gli elementi delle voci, ovvero gli UL che sono posizionati SUBITO DOPO i TAG LI con classe Menu.
Dobbiamo distinguerli in qualche modo dagli altri UL e per far questo possiamo assegnarli una classe inesistente, servirà soltanto alla nostra funzione per capire se l'UL in questione è un raggruppamento di righe nella voce o no.


Il nostro codice, dopo l'ultima modifica, sarà:
 
    <ul>
        <li class="Menu"><a href="#">Voce 1</a>
            <ul class="Sottomenu">
                <li><a href="#">riga 1 voce 1</a></li>
                <li><a href="#">riga 2 voce 1</a></li>
                <li><a href="#">....</a></li>
                <li><a href="#">riga N voce 1</a></li>
                <li class="Menu"><a href="#">Sotto-Voce 1</a>
                    <ul class="Sottomenu">
                        <li><a href="#">riga 1 sotto-voce 1</a></li>
                        <li><a href="#">riga 2 sotto-voce 1</a></li>
                        <li><a href="#">...</a></li>
                        <li><a href="#">riga N sotto-voce 1</a></li>
                    </ul>
                </li>
            </ul>
        </li>
        <li class="Menu"><a href="#">Voce 2</a>
            <ul class="Sottomenu">
                <li><a href="#">riga 1 voce 2</a></li>
                <li><a href="#">riga 2 voce 2</a></li>
                <li><a href="#">...</a></li>
                <li><a href="#">riga N voce 2</a></li>
            </ul>
        </li>
    </ul>



Bene bene, siamo riusciti ora a distinguere il tipo di UL, da uno normale ad uno che rappresenta un gruppo di righe. Ma dobbiamo ora specificare in maniera univoca quale UL intendiamo nascondere, altrimenti la nostra funzione nasconderà TUTTI gli UL che raggruppano le righe delle voci!!
Per far questo impostiamo un ID agli UL. Possiamo sbizzarrirci nel creare l'ID e dar sfogo a tutta la nostra fantasia, tanto l'identificativo serve solo ed esclusivamente ad indirizzare la funzione sull'oggetto che vogliamo modificare!
Un bello sfoggio di brillante genialità l'ho dimostrato nell'esempio. L'UL che contiene le righe della Voce 1 l'ho chiamato Voce-1 così come Voce-2 è il gruppo di righe della Voce 2 e così via!

    <ul>
        <li class="Menu"><a href="#">Voce 1</a>
            <ul class="Sottomenu" id="Voce-1">
                <li><a href="#">riga 1 voce 1</a></li>
                <li><a href="#">riga 2 voce 1</a></li>
                <li><a href="#">....</a></li>
                <li><a href="#">riga N voce 1</a></li>
                <li class="Menu"><a href="#">Sotto-Voce voce 1</a>
                    <ul class="Sottomenu" id="Sotto-Voce-voce-1">
                        <li><a href="#">riga 1 sotto-voce 1</a></li>
                        <li><a href="#">riga 2 sotto-voce 1</a></li>
                        <li><a href="#">...</a></li>
                        <li><a href="#">riga N sotto-voce 1</a></li>
                    </ul>
                </li>
            </ul>
        </li>
        <li class="menu"><a href="#">Voce 2</a>
            <ul class="Sottomenu" id="Voce-2">
                <li><a href="#">riga 1 voce 2</a></li>
                <li><a href="#">riga 2 voce 2</a></li>
                <li><a href="#">...</a></li>
                <li><a href="#">riga N voce 2</a></li>
            </ul>
        </li>
    </ul>




Perfetto! Ora siamo pronti per il lato javascript del tutorial!!
Vediamo di capire un attimino cosa ci si aspetta dalla funzione.
Come avevo accennato prima il nostro scopo è di sfruttare le potenzialità di una opzione dello stile degli UL, l'opzione "display".
Se imposto questa variabile a "none" l'UL viene chiuso e non mi mostra le righe LI al suo interno.
Al contrario, se la imposto a "block" il menu e tutti i suoi elementi diventano visibili.

Iniziamo allora a chiudere tutti i menù all'apertura della pagina. Per far questo dobbiamo individuare TUTTI gli UL dei menù ed impostare la proprietà "display" a "none".
Questa procedura viene svolta dalla funzione collapseALL():

    //Chiude tutti i menù
    function collapseALL()
        {
            //NASCONDE IL MENU
            //inserisce in una collezione di oggetti tutti i TAG UL del documento

            var uls = document.getElementsByTagName("ul");
           
            //per ogni TAG UL ripete il seguente controllo:
            for (i=0;i<uls.length;i++)
                {   
                    //Se il nome della classe e "Sottomenu" allora imposta "display" a "none".
                    if(uls[i].className=="Sottomenu")uls[i].style.display = "none";
                }
            //CAMBIA LE ICONE DELLA CARTELLA
            //inserisce in una collezione di oggetti tutti i TAG LI del documento

            var lis = document.getElementsByTagName("LI");
           
            //per ogni TAG LI ripete il seguente controllo:
            for (i=0;i<lis.length;i++)
                {   
                    //Se il nome della classe e "Menu" allora imposta "listStyleImage" a "closedfolder.png".
                    if(lis[i].className=="Menu")lis[i].style.listStyleImage = "url(closedfolder.png)" ;
                }
        }


Semplice no?!

E per farla eseguire automaticamente all'avvio della pagina basta inserirla nella proprietà onload del TAG BODY:

    <BODY onload="javascript:collapseALL();">

Ora concentriamoci sulla funzione che ci consente di far funzionare i menù:

    //Mostra/Nasconde i menù
    function MostraMenu(IDmenu)
        {
            //Carico l'oggetto UL che devo modificare
            var menu = document.getElementById(IDmenu);
           
            //Controllo lo stato dell'opzione display
            var display = menu.style.display;
           
            //se lo stato è a "block" la imposta a "none" e vice versa
            menu.style.display = (display == "block") ? "none" : "block";

            //modifica l'icona a closedfolder.png se display è block, altrimenti la imposta a openfolder.png
            menu.parentNode.style.listStyleImage = (display == "block") ? "url(closedfolder.png)" : "url(openfolder.png)";
        }

La funzione è pronta, non resta che farla richiamare al click del mouse passando in argomento l'ID del sottomenù che deve azionare.
Per far questo andiamo ad inserire un link nei TAG LI di tipo MENU:

    <ul>
        <li class="Menu"><a href="javascript:MostraMenu('Voce-1')">Voce 1</a>
            <ul class="Sottomenu" id="Voce-1">
                <li><a href="#">riga 1 voce 1</a></li>
                <li><a href="#">riga 2 voce 1</a></li>
                <li><a href="#">....</a></li>
                <li><a href="#">riga N voce 1</a></li>
                <li class="Menu"><a href="javascript:MostraMenu('Sotto-Voce-voce-1')">Sotto-Voce 1</a>
                    <ul class="Sottomenu" id="Sotto-Voce-voce-1">
                        <li><a href="#">riga 1 sotto-voce 1</a></li>
                        <li><a href="#">riga 2 sotto-voce 1</a></li>
                        <li><a href="#">...</a></li>
                        <li><a href="#">riga N sotto-voce 1</a></li>
                    </ul>
                </li>
            </ul>
        </li>
        <li class="menu"><a href="javascript:MostraMenu('Voce-2')">Voce 2</a>
            <ul class="Sottomenu" id="Voce-2">
                <li><a href="#">riga 1 voce 2</a></li>
                <li><a href="#">riga 2 voce 2</a></li>
                <li><a href="#">...</a></li>
                <li><a href="#">riga N voce 2</a></li>
            </ul>
        </li>
    </ul>



Il nostro menù è pronto! Se vogliamo possiamo servirlo ai nostri ospiti (web) così, o arricchirlo di funzioni comode come dei tasti per l'apertura e la chiusura simultanea di tutte le voci di menù, comodo se stiamo cercando una voce specifica e non vogliamo impazzire a furia di click!
Partiamo dalla funzione collapseALL() e modifichiamo solo l'impostazione del display, da "none" a "block":

    //apre tutti i menù
    function expandALL()
        {
            //MOSTRA I MENU
            //inserisce in una collezione di oggetti tutti i TAG UL del documento

            var uls = document.getElementsByTagName("UL");
           
            //per ogni TAG UL ripete il seguente controllo:
            for (i=0;i<uls.length;i++)
                {   
                    //Se il nome della classe e "Sottomenu" allora imposta "display" a "block".
                    if(uls[i].className=="Sottomenu")uls[i].style.display = "block";       
                }
           
            //CAMBIA LE ICONE DELLA CARTELLA
            //inserisce in una collezione di oggetti tutti i TAG LI del documento

            var lis = document.getElementsByTagName("LI");
           
            //per ogni TAG LI ripete il seguente controllo:
            for (i=0;i<lis.length;i++)
                {   
                    //Se il nome della classe e "Menu" allora imposta "listStyleImage" a "openfolder.png".
                    if(lis[i].className=="Menu")lis[i].style.listStyleImage = "url(openfolder.png)" ;
                }
           
        }


Possiamo inserire queste funzioni in due pulsanti nella pagina:
 
      <form>
        <input type="button" onClick="javascript:expandALL();" value="Apri Tutti">
        <input type="button" onClick="javascript:collapseALL();" value="Chiudi Tutti">
    </form>




Ed ora è proprio tutto pronto!

Ricapitolando il codice, lo stesso visibile in azione in questo esempio , sarà:

    <HTML>
        <HEAD>
            <META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
            <META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
            <META HTTP-EQUIV="EXPIRES" CONTENT="0">
            <STYLE type="text/css">
                <!--
                body     {
                        font: .80em verdana, helvetica, sans-serif;   
                    }
       
                ul     {
                        list-style: disc url(document.png);
                        margin:0;padding:0 2em;
                    }
       
                li.Menu {
                        list-style: square url(closedfolder.png);
                    }
                -->
            </STYLE>   
        </HEAD>

        <SCRIPT language="javascript">
           
            //Chiude tutti i menù
            function collapseALL()
                {
                    //NASCONDE IL MENU
                    //inserisce in una collezione di oggetti tutti i TAG UL del documento

                    var uls = document.getElementsByTagName("UL");
                   
                    //per ogni TAG UL ripete il seguente controllo:
                    for (i=0;i<uls.length;i++)
                        {   
                            //Se il nome della classe e "Sottomenu" allora imposta "display" a "none".
                            if(uls[i].className=="Sottomenu")uls[i].style.display = "none";
                        }
                    //CAMBIA LE ICONE DELLA CARTELLA
                    //inserisce in una collezione di oggetti tutti i TAG LI del documento

                    var lis = document.getElementsByTagName("LI");
                   
                    //per ogni TAG LI ripete il seguente controllo:
                    for (i=0;i<lis.length;i++)
                        {   
                            //Se il nome della classe e "Menu" allora imposta "listStyleImage" a "closedfolder.png".
                            if(lis[i].className=="Menu")lis[i].style.listStyleImage = "url(closedfolder.png)" ;
                        }
                }
           
            //apre tutti i menù
            function expandALL()
                {
                    //MOSTRA I MENU
                    //inserisce in una collezione di oggetti tutti i TAG UL del documento

                    var uls = document.getElementsByTagName("UL");
                   
                    //per ogni TAG UL ripete il seguente controllo:
                    for (i=0;i<uls.length;i++)
                        {   
                            //Se il nome della classe e "Sottomenu" allora imposta "display" a "block".
                            if(uls[i].className=="Sottomenu")uls[i].style.display = "block";       
                        }
                   
                    //CAMBIA LE ICONE DELLA CARTELLA
                    //inserisce in una collezione di oggetti tutti i TAG LI del documento

                    var lis = document.getElementsByTagName("LI");
                   
                    //per ogni TAG LI ripete il seguente controllo:
                    for (i=0;i<lis.length;i++)
                        {   
                            //Se il nome della classe e "Menu" allora imposta "listStyleImage" a "openfolder.png".
                            if(lis[i].className=="Menu")lis[i].listStyleImage = "url(openfolder.png)" ;
                        }
                   
                }
           
            //Mostra/Nasconde i menù
            function MostraMenu(IDmenu)
                {
                    //Carico l'oggetto UL che devo modificare
                    var menu = document.getElementById(IDmenu);
                   
                    //Controllo lo stato dell'opzione display
                    var display = menu.style.display;
                   
                    //se lo stato è a "block" la imposta a "none" e vice versa
                    menu.style.display = (display == "block") ? "none" : "block";
           
                    //modifica l'icona a closedfolder.png se display è block, altrimenti la imposta a openfolder.png
                    menu.parentNode.style.listStyleImage = (display == "block") ? "url(closedfolder.png)" : "url(openfolder.png)";
                }
   
        </SCRIPT>
       
        <BODY onload="javascript:collapseALL();">
            <TABLE>
                <TR>
                    <TD>
                        <FORM>
                            <input type="button" onClick="javascript:expandALL();" value="Apri Tutti">
                            <input type="button" onClick="javascript:collapseALL();" value="Chiudi Tutti">
                        </FORM>
                    </TD>
                </TR>
                <TR>
                    <TD>
                        <UL>
                            <LI class="Menu"><a href="javascript:MostraMenu('Voce-1')">Voce 1</a>
                                <UL class="Sottomenu" id="Voce-1">
                                    <LI><a href=
"#">riga 1 voce 1</a></LI>
                                    <LI><a href=
"#">riga 2 voce 1</a></LI>
                                    <LI><a href=
"#">....</a></li>
                                    <LI><a href=
"#">riga N voce 1</a></LI>
                                    <LI class="Menu"><a href="javascript:MostraMenu('Sotto-Voce-voce-1')">Sotto-Voce1</a>
                                        <UL class="Sottomenu" id="Sotto-Voce-voce-1">
                                            <LI><a href=
"#">riga 1 sotto-voce 1</a></LI>
                                            <LI><a href=
"#">riga 2 sotto-voce 1</a></LI>
                                            <LI><a href=
"#">...</a></li>
                                            <LI><a href=
"#">riga N sotto-voce 1</a></LI>
                                        </UL>
                                    </LI>
                                </UL>
                            </LI>
                            <LI class="Menu"><a href="javascript:MostraMenu('Voce-2')">Voce 2</a>
                                <UL class="Sottomenu" id="Voce-2">
                                    <LI><a href=
"#">riga 1 voce 2</a></LI>
                                    <LI><a href=
"#">riga 2 voce 2</a></LI>
                                    <LI><a href=
"#">...</a></LI>
                                    <LI><a href="#">riga N voce 2</a></LI>
                                </UL>
                            </LI>
                        </UL>
                    <TD>
                </TR>
            </TABLE>
        </BODY>
    <HTML>