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:
<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 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
Il CSS
Dato che il protagonista essenziale dell'articolo è il Javascript, vediamo en passant il CSS per intero.
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
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:
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:
- Verificare se il browser supporta il DOM. In caso negativo, lo script non farà niente e verrà presentata la versione senza Javascript.
- Attribuire al div id="nav" la classe CSS jsenable
- Per ogni h3 del menu, all'onclick assegna la classe CSS show hide 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
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 div id="nav" da Javascript. Le classi show hide
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
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:
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
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.