20 Giugno ’06

Separare le azioni / animazioni, dal resto

di Jeremy Keith.

"Translated with the permission of A List Apart Magazine."

Separare, le animazioni o azioni, dal resto non è facile da fare, ma nel web design può essere una buona cosa. Il contenuto, lo stile e le azioni, meritano ognuno il suo spazio.

Guida di Stile

Gatto

Uno dei vantaggi dell'uso dei fogli di stile è proprio la separazione dello stile dal contenuto

Si potrebbe realizzare lo stile di un intero sito soltanto utilizzando dichiarazioni in linea come questa:

<p style="font-weight: bold; color: red;">Questo testo è importante</p>

Ma allora utilizzeremmo semplicemente i tag <font>.
Ha molto più senso salvare lo stile in un'altro file e mettere degli agganci ad esso nel markup.

Markup: <p class="importante">Questo testo è importante</p>
CSS: p.importante { font-weight: bold; color: red; }

Questo rende la vita di tutti più facile. In questo modo si può modificare velocemente lo stile e cambiare il colore del testo nero a rosso, per esempio. E' meglio per il visitatore che non deve scaricare pagine gonfie di codice.

Questo vale anche per il JavaScript ma, sfortunatamente un sacco di Java script si trova ancora all'interno delle pagine stesse.

Tutto è superficialmente interconnesso

Supponi di voler aggiunge una qualche animazione a un link.

puoi usare uno pseudo controllo in Javascript:

<a href="javascript: faiQualcosa();">Clicca e Divertiti</a>

Questo è un approccio miope. I software che non supportano JavaScript si bloccheranno sul valore href qui sopra.

<a href="#" onclick="faiQualcosa();">Clicca e Divertiti</a>

Questo è un pò meglio ma è semanticamente senza senso. Perché usare un link se non và da nessuna parte ?

<a href="paginavera.html" onclick="faiQualcosa(); return false;">Clicca e Divertiti</a>

Ci stiam avvicinando. Questo link funsiona anche se il JavaScript è disabilitato (e, per la prima volta il link è leggibile dagli Spider dei motori di ricerca).

Ma il problema rimane perché la gestione degli eventi è ancora mischiata con il markup.

I gestori di eventi in linea sono l'equivalente delle dichiarazini di stile in linea. Fortunatamente questi possono essere rimossi e messi in un file separato come avviene per i CSS per poi aggiungere degli agganci nel markup e andare a beccare gli elementi che vuoi animare.

<a href="paginavera.html" class="divertente">Clicca e Divertiti</a>

Per esempio puoi scrivere, in un file JavaScript esterno, uno script per trovare tutti i links che hanno className "divertente" e fargli eseguire una cerca funzione quando vengono cliccati.

La separazione del markup dalle azioni/animazioni è chiamato JavaScript non intrusivo (o discreto).

Basta teoria. vediamo come applicare questa tecnica al mondo reale.

La galleria dell’imbroglione

Due anni fà ho scritto un articolo per "A List Apart" sulla costruzione di Gallerie di Immagini in JavaScript. Il JavaScript descritto nell'articolo funziona bene ma guardiamo il markup:

<ul>
<li><a onclick="return mostraImm(this)" »
href="image/banana.jpg" title="Un pezzo di banana »
sul tavolo">alcune banane</a></li>
<li><a onclick="return mostraImm(this)" »
href="image/condimenti.jpg" title="Condimenti in un »
ristorante cinese">due bottigliette</a></li>

<li><a onclick="return mostraImm(this)" »
href="image/conchiglie.jpg" title="Conchiglie sul tavolo"> »
alcune conchiglie</a></li>
</ul>

Troppi gestori di eventi che si ripetono sono intrusivi, potrei sostituirli con delle Classi

<ul>
<li><a class="immgalleria" href="image/banana.jpg" »
title="Un pezzo di banana sul tavolo">alcune banane</a></li>
<li><a class="immgalleria" href="image/condimenti.jpg" »
title="Condimenti in un ristorante cinese">due bottigliette</a></li>

<li><a class="immgalleria" href="image/conchiglie.jpg" »
title="conchigliesultavolo">alcune conchiglie</a></li>
</ul>

Ma anche questo in fine è ripetitivo. Non avrei fatto così se avessi voluto applicare uno stile ad ogni elemento della lista e non c'è bisogno di farlo neanche per applicare delle azioni, posso semplicemente aggiungere un id alla lista

<ul id="galleria_imm">
<li><a href="image/banana.jpg" title="Un pezzo di »
banana sul tavolo">alcune banane</a></li>
<li><a href="image/condimenti.jpg" title="Condimenti »
in un ristorante cinese">due bottigliette</a></li>

<li><a href="image/conchiglie.jpg" title="Conchiglie su un »
tavolo">alcune conchiglie</a></li>
</ul>

Ora devo soltanto scrivere una funsione per aggiungere il gestore degli eventi dall'esterno.

Voglia di separazione

Ora scriveremo una funsione chiamata preparaGalleria. Questa funsione usera il Document Object Model (DOM) per trovare i link desiderati, nel documento.
Il tutto grazie hai metodi getElementById e getElementByTagName("a");

document.getElementById("galleria_imm").getElementsByTagName("a");

Questo metodo funziona un pò come i selettori nei CSS. E' come combinate id e selezione dell'elemento:

#imagegallery a

Ecco cosa voglio fare:

  • Assicurarmi che il Browser capisca i metodi DOM che userò
  • Assicurarmi che ci sia un elemento con ID "galleria_imm."
  • Prendere la lista con ID "galleria_imm"
  • Prendere tutti i link nella lista
  • Aggiungere l'evento onclick ad ogni link e collegarlo alla funsione mostraImm

Questa è la funzione in Java Script:

function preparaGalleria(){
if( document.getElementById &&
document.getElementsByTagName ){
if( document.getElementById( 'galleria_imm' ) ){
var galleria = document.getElementById( 'galleria_imm' );
var links = galleria.getElementsByTagName( 'a' );
for( var i=0; i < links.length; i++ ){
links[i].onclick = function(){
return mostraImm(this);
};
}
}
}
}

Ora che ho scritto la funzione devo solo lanciarla, ma c'è un problema. Non posso semplicemente scrivere:

prepareGallery();

Se lo facessi, la funsione (che è in un file estrerno o nell'HEAD del documento) verra eseguita prima che il resto del documento finisca il caricamento e il metodo DOM non funzionerà. Senza il completo caricamento non può esserci un modello di documento.

Bisogna aspettare che tutto sia stato caricato. Fortunatamento, il caricamento del documento può essere tracciato dall'evento load all'interno dell’oggetto window. posso usare il comando windows.onload ed assegnare la funzione preparaGalleria a questo evento:

window.onload = preparaGalleria;

A questo proposito leggi la funzione di Simon Willison addLoadEvent

Prove di separazione

Il JavaScript non intrusivo è un'idea relativamente nuova, se vuoi provare segui questi consigli:

  • Inizia dal contenuto
  • Dagli una struttura con markup descrittivo e semanticamente corretto
  • Applica un layout che separi lo stile dal resto usando i CSS
  • Aggiungi dei animazioni e comportamenti con gli script DOM

Ma fai attenzione a non strafare

Sull’Autore

Jeremy Keith Jeremy Keith è uno sviluppatore Irlandese che vive e lavora a Brighton, nel sud dell'Inghilterra. Quando non è intento a creare siti web, gioca a bouzouki con la band Salter Cane. Il suo sito personale è Adactio.