Secondo capitolo del corso di Javascript non intrusivo. Dopo aver pulito il codice HTML, impariamo a raggiungere gli elementi da modificare nella nostra pagina.
Capitolo 2: Raggiungere cosa si vuole cambiare
Per gli sviluppatori Javascript inesperti, l’HTML è come un parco giochi.
HTML:
o nel caso siano un minimo più preparati:
HTML:
Javascript:
// preloading image
homeoff = new Image();
homeoff.src = ‘home.gif’;
homeon = new Image();
homeon.src = ‘homeoff.gif’;
function roll(imgName,a){
imgState=a==0?eval(imgName + ‘on.src’):eval(imgName + ‘off.src’);
document.images[imgName].src = imgState;
}
In ogni caso, tutti le chiamate di eventi sono nel codice HTML, e se cambia il nome della funzione, è necessario cambiare ogni documento. Inoltre, ogni rollover significa diverso markup che viene aggiunto al peso complessivo della pagina.
Via! Via! – voi demoni delle chiamate di eventi inline
Dimentichiamo per il momento che praticamente ogni effetto di rollover attualmente può essere effettuato via CSS anzichè via Javascript – diciamo che vogliamo usare il seguente markup e creare un rollover per questa immagine:
HTML:
Ora, come cambiare quando il mouse è posizionato sopra a questa?
Scalare i rami del node tree
Ogni documento XML (e questo include HTML) è un albero a nodi (node tree). Un nodo è parte di quest’albero (pensate a un file o una cartella nell’explorer di windows quando esplorate il vostro hard disk). Un nodo può essere dodici cose differenti – per l’HTML solo tre sono realmente interessanti: element, TextNode e AttributeNode.
La nostra attrezzatura da arrampicata
Vediamo quali funzioni e attributi possiamo usare per navigare il node tree di un documento, e come saltare da un elemento all’altro.
Funzioni per raggiungere un elemento nella pagina
getElementById(’elementID’)
restituisce l’elemento con l’ID elementID come un oggetto.
getElementsByTagName(’tag’)
restituisce tutti gli elementi con il nome tag come una array.
Ovviamente le due funzioni possono essere mescolate e integrate. Alcuni esempi:
Javascript:
document.getElementById(’navigation’).getElementsByTagName(’a')[3];
//returns the fourth link inside the element with the ID ‘navigation’
document.getElementsByTagName(’div’)[2].getElementsByTagName(’p')[0];
//returns the first paragraph inside the third div in the document.
Strumenti per navigare a partire da un certo elemento
childNodes
restituisce una array con tutti i nodi all’interno del nodo corrente. Sono presenti anche firstChild e lastChild, che sono versioni brevi di childNodes[0] e childNodes[this.childNodes.lenght-1].
parentNode
l’elemento che contiene il nostro nodo
nextSibling
l’elemento successivo allo stesso livello nel document tree.
previousSibling
l’elemento precedente allo stesso livello nel document tree.
Tutte queste funzioni possono essere mescolate secondo necessità.
Javascript:
var other=document.getElementById(’nav’).childNodes[3].firstChild;
//returns the 4th element’s first sub element inside the element
//with the ID nav.
var prevlink=o.parentNode.previousSibling.firstChild.childnodes[2];
//returns the third node inside the previous element
//that is on the same level as the parent element of o.
Attributi e funzioni per gli elementi
attributes
data
nodeName
nodeType
nodeValue
getAttribute(attribute)
Javascript:
var other=document.getElementById(’nav’).firstChild;
if(other.nodeType==3){
other.data=’newtext’;
}
if(other.nodeType==1){
other.firstChild.data=’newtext’;
}
Ora per raggiungere l’immagine del nostro esempio, possiamo usare sia getElementsByTagName che getElementById.
HTML:
Usare getElementById è decisamente più semplice, in quanto non è necessario ciclare attraverso tutti gli elementi e trovare un identificativo univoco. In questo esempio, controlliamo che l’attributo src dell’oggetto immagine contenga ‘home.gif’. Una tecnica comune è di cercare una classe speciale.
HTML:
Javascript:
function findimg()
{
var imgs,i;
imgs=document.getElementsByTagName(’img’);
for(i in imgs)
{
if(/roll/.test(imgs[i].className))
{
imgs[i].style.border=’3px dashed #ccc’;
}
}
}
Ora, per aggiungere un effetto rollover, tutto ciò di cui abbiamo bisogno è di aggiungere una funzione che effettui lo scambio della sorgente dell’immagine, e aggiunga il gestore di evento all’immagine.
Javascript:
function findimg()
{
var imgs,i;
// loop through all images of the document
imgs=document.getElementsByTagName(’img’);
for(i=0;i
// test if the class 'roll' exists
if(/roll/.test(imgs[i].className))
{
// add the function roll to the image onmouseover and onmouseout and send
// the image itself as an object
imgs[i].onmouseover=function(){roll(this);};
imgs[i].onmouseout=function(){roll(this);};
}
}
}
function roll(o)
{
var src,ftype,newsrc;
// get the src of the image, and find out the file extension
src = o.src;
ftype = src.substring(src.lastIndexOf('.'), src.length);
// check if the src already has an _on and delete it, if that is the case
if(/_on/.test(src))
{
newsrc = src.replace('_on','');
}else{
// else, add the _on to the src
newsrc = src.replace(ftype, '_on'+ftype);
}
o.src=newsrc;
}
window.onload=function(){
findimg();
}
Prova questo esempio su onlinetools.org
Buono per il momento, ma abbiamo dimenticato una cosa: oltre ad essere un mero elemento grafico, un rollover dovrebbe funzionare anche in assenza di un mouse. Per ottenere questo, dobbiamo controllare se il collegamento attorno all’immagine ottiene o meno il focus, dato che l’immagine stessa non è raggiungibile tramite tastiera quando incastonata in un link.
Per fare questo, abbiamo bisogno di raggiungere l’elemento che contiene l’immagine, in questo caso il collegamento. Faremo questo tramite il comando parentNode. Dato che questo cambia l’oggetto che verrà inviato come parametro alla funzione roll(), abbiamo bisogno di trovare nuovamente l’immagine. Quindi compieremo un ciclo attraverso i childNodes del collegamento e cercheremo quale di questi è un elemento e una immagine, controllando nodeType e nodeName. Questo è necessario, in quanto alcuni browser interpretano lo spazio bianco nel codice sorgente come un nodo, a differenza di altri.
Javascript:
function findimg()
{
var imgs,i;
// Loop through all images, check if they contain the class roll
imgs=document.getElementsByTagName(’img’);
for(i=0;i
if(/roll/.test(imgs[i].className))
{
// add the function roll to the parent Element of the image
imgs[i].parentNode.onmouseover=function(){roll(this);};
imgs[i].parentNode.onmouseout=function(){roll(this);};
imgs[i].parentNode.onfocus=function(){roll(this);};
imgs[i].parentNode.onblur=function(){roll(this);};
}
}
}
function roll(o)
{
var i,isnode,src,ftype,newsrc,nownode;
// loop through all childNodes
for (i=0;i
nownode=o.childNodes[i];
// if the node is an element and an IMG set the variable and exit the loop
if(nownode.nodeType==1 && /img/i.test(nownode.nodeName))
{
isnode=i;
break;
}
}
// check src and do the rollover
src = o.childNodes[isnode].src;
ftype = src.substring(src.lastIndexOf('.'), src.length);
if(/_on/.test(src))
{
newsrc = src.replace('_on','');
}else{
newsrc = src.replace(ftype, '_on'+ftype);
}
o.childNodes[isnode].src=newsrc;
}
window.onload=function(){
findimg();
}
Prova questo esempio indipendente dal mouse su onlinetools.org
Perchè non provi?
Esercitazioni consigliate online alla pagina
http://www.onlinetools.org/articles/unobtrusivejavascript/chapter2.html

alt="home">