Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Un menu espandibile con Javascript e CSS

Terza parte della serie su interattività ed eventi in Javascript
Terza parte della serie su interattività ed eventi in Javascript
Link copiato negli appunti

Arriviamo con questo articolo alla parte conclusiva della serie sull'interazione con Javascript. Abbiamo visto come sfruttando questo linguaggio sia possibile modificare proprietà CSS e attribuire classi ad elementi di pagina, creare elementi dinamicamente e soprattutto gestire gli eventi. In questo appuntamento, vedremo come realizzare un menu espandibile in due versioni.

Un menu espandibile a due livelli

Iniziamo a vedere subito il primo esempio: si tratta di un menu espandibile con HTML, CSS e Javascript. Le tre componenti essenziali sono totalmente separate, e Javascript risiede su un livello superiore rispetto ad HTML e CSS: ecco come renderebbe l'esempio con Javascript disabilitato. Come si può notare, il menu si presenta interamente espanso e i link sono in chiaro. Per l'accessibilità, è infatti essenziale che l'utente possa consultare la pagina con un browser obsoleto (e quindi non-DOM compatibile), con Javascript abilitato, con un browser testuale o con uno screenreader. Ora, non ci resta che procedere e costruire il nostro menu passo passo con HTML, CSS e Javascript.

Il codice HTML

Il codice HTML dell'esempio è molto semplice: si tratta di una lista principale con sottoliste annidate in cui ogni voce principale del menu è racchiusa in un titolo h3, seguita dal relativa sottomenu:

<div id="nav">
<ul>
    <li><a href="http://pro.HTML.it">Home Page</a></li>
    <li><h3>Linguaggi</h3>
        <ul>
            <li><a href="#">CSS</a></li>
            <li><a href="#">Javascript</a></li>
            <li><a href="#">DOM</a></li>
            <li><a href="#">PHP</a></li>
        </ul>
    </li>
    <li><h3>Software</h3>
        <ul>
            <li><a href="#">Photoshop</a></li>
            <li><a href="#">Flash</a></li>
            <li><a href="#">Fireworks</a></li>
            <li><a href="#">Dreamweaver</a></li>
        </ul>
    </li>
    <li><h3>Webdesign</h3>
        <ul>
            <li><a href="#">Webdesign</a></li>
            <li><a href="#">Accessibilità</a></li>
            <li><a href="#">Usabilità</a></li>
        </ul>
    </li>
</ul>
</div>

In sostanza, nell'HTML è essenziale che le voci principali (o di primo livello) vengano racchiuse in dei titoli h3, e che non siano link se questi indicano sottomenu. Vi potrete rifare al codice appena visto per i vostri progetti.

Il markup è semantico, e oltretutto, come vedremo, serve a segnalare le voci di primo livello a Javascript per rendere il menu espandibile. Ecco come si presenta la pagina in HTML puro. Un po' scarno, non è vero? Procediamo allora ad aggiungere gli altri due ingredienti: presentazione e interazione.

Il CSS

Dato che il protagonista essenziale dell'articolo è il Javascript, vediamo en passant il CSS per intero.

div#nav{width:170px;margin-left: 30px;background: #00005A;
    border: 1px solid #00005A; font: 11px Arial, Helvetica, sans-serif}
div#nav h3{font-size: 100%;margin: 0;padding: 4px 10px;
    border-top: 1px solid #FFF;color: #000;background-color: #7BA5E7}
div#nav ul,div#nav li{margin: 0;padding: 0;list-style-type: none}
div#nav li{margin: 0 0 1px 0}
div#nav a{display: block;padding-left: 15px;height: 18px;line-height: 18px;
    border-top: 1px solid #FFF;background-color: #BDBDBD;color: #000;
    text-decoration: none;font-weight: bold}
div#nav a:hover{color: #00005A;background-color: #0099FF}
div#nav ul ul a{color: #333; background-color: #AECDFF;font-weight: normal}

Ovviamente, potrete modificare il CSS a vostro piacimento. L'interazione in effetti avviene tra HTML, Javascript e cinque semplici regolette che, più che per la presentazione, servono per aggiungere interazione al menu. È per questo motivo che ho deciso di tenerle in un CSS separato che presenterò tra breve e che comunque non ha nessun effetto in assenza di Javascript. Ecco come si presenta il menu con il codice che abbiamo visto finora. Non ci resta che la componente essenziale ai fini dell'esempio: l'interazione.

Azione! Javascript e CSS all'opera

La parte essenziale dell'esempio è una miscela di Javascript e CSS. Si sarebbe potuto aggiungere l'interazione esclusivamente grazie a Javascript, ma ritengo che in questo caso ci debba essere una sorta di presentazione interattiva. Iniziamo con lo script, che è sorprendentemente breve e come al solito usa estensivamente il DOM:

window.onload=function(){
if(document.getElementsByTagName && document.getElementById){
    document.getElementById("nav").className="jsenable";
    BuildList();
    }
}

function BuildList(){
var hs=document.getElementById("nav").getElementsByTagName("h3");
for(var i=0;i<hs.length;i++){
    hs[i].onclick=function(){
        this.parentNode.className=(this.parentNode.className=="show") ? "hide" : "show";
        }
    }
}

Lo script, invocato al caricamento di pagina, si occupa di:

  1. Verificare se il browser supporta il DOM. In caso negativo, lo script non farà niente e verrà presentata la versione senza Javascript.
  2. Attribuire al div id="nav" la classe CSS jsenable che 'collassa' in un colpo solo tutti i sottomenu.
  3. Per ogni h3 del menu, all'onclick assegna la classe CSS show o hide all'li che lo contiene per mostrare o nascondere i sottomenu.

Per sottolineare cosa ci rimane da fare, ho riportato in grassetto le classi CSS necessarie che vengono usate esclusivamente per servire lo script. Ho pensato di separarle dal codice CSS centrale perchè hanno questo scopo ben preciso. Eccole:

div.jsenable h3{cursor: pointer}
div.jsenable ul ul{display:none}
div#nav li.hide ul{display:none}
div#nav li.show ul{display:block}
div#nav li.show h3{background-color: #FF0}

Le regole sopra si occupano di attribuire il cursore "a manina" per i titoli e nascondere tutte le voci di secondo livello al caricamento di pagina, grazie alla classe jsenable attribuita al div id="nav" da Javascript. Le classi show e hide, attribuite alternativamente ai list-item di primo livello, vengono aggiunte da Javascript all'onclick sui titoli, e si occupano di mostrare e nascondere le voci di secondo livello. Infine, aggiungiamo ai titoli un colore giallo quando questi indicano un sottomenu espanso.

C'è da notare che le regole appena viste non hanno nessuna interferenza con la presentazione della pagina nel caso in cui Javascript sia disabilitato, dato che riguardano classi aggiunte da Javascript stesso e non presenti nel codice HTML. È un caso in cui i fogli di stile, anzichè risiedere a livello di presentazione, unitamente al Javascript vanno a creare un livello di interazione ben miscelato.

Il nostro esempio è così ultimato, perfettamente standard e accessibile. Per finire, una piccola nota. È buona pratica separare totalmente Javascript e CSS dall'HTML, usando le inclusioni. Nell'esempio ho preparato tre file da importare nell'HTML in questo modo:

<link rel="stylesheet" type="text/CSS" href="jsmenu.CSS">
<link rel="stylesheet" type="text/CSS" href="menu.CSS">
<script type="text/Javascript" src="expand.js"></script>

Di modo che più pagine possano usare i CSS e il Javascript esterni senza dover replicare il codice in tutte, e garantire una presentazione e un'interazione consistente per un intero sito. A questo punto, non ci resta che vederne una variante.

Un menu espandibile con massimo una voce aperta

Con una piccola modifica al codice Javascript dell'esempio appena visto, possiamo ottenere un menu espandibile con al massimo una voce aperta, a parer mio molto più indicato se si dispone di un menu con molte voci tale da generare scrolling verticale se si mostra totalmente espanso. Rispetto all'esempio precedente, ho voluto aggiungere nell'HTML tutte le voci che compongono le varie sezioni di Pro per realizzare un menu un po' corposo. Il CSS è rimasto invariato. mentre il Javascript ha qualche modifica. Vediamolo:

var prev= null;

window.onload=function(){
if(document.getElementsByTagName && document.getElementById){
    document.getElementById("nav").className="jsenable";
    BuildList();
    }
}

function BuildList(){
var hs=document.getElementById("nav").getElementsByTagName("h3");
for(var i=0;i<hs.length;i++){
    hs[i].onclick=function(){
        if(this.parentNode.className!="show"){
            this.parentNode.className="show";
            if(prev && prev!=this.parentNode) prev.className="hide";
            prev=this.parentNode;
            }
        else this.parentNode.className="hide";
        }
    }
}

Lo script intercetta gli eventi onclick sugli header, e oltre a espandere una voce, si preoccupa di nascondere la voce già aperta. Nel caso che l'onclick venga effettuato sull'h3 relativo alle voce aperta, questa semplicemente viene chiusa, garantendo così che ci sia al massimo un sottomenu espanso.

Senza dubbio, Javascript in questo caso può contriubire molto a migliorare l'usabilità e la consultazione del menu rispetto all'analogo con Javascript disabilitato, che resta comunque utilizzabile e con tutti i link in chiaro.

Conclusioni

Si conclude qui la serie di articoli dedicati all'interazione e gli eventi con Javascript, in cui abbiamo visto diversi esempi di come Javascript possa costituire un extra non indifferente per migliorare l'usabilità di un sito. L'approccio alla separazione del codice e alla gestione dell'interazione al di sopra di contenuto è presentazione è però essenziale per far sì che simili vantaggi non diventino rovinosi per l'utente se Javascript per qualche motivo non può girare. Il codice degli esempi è disponibile per il download. Alla prossima.

Ti consigliamo anche