back to top

Lโ€™oggetto document di Javascript e lโ€™interazione col DOM

Il Document Object Model (o, piรน brevemente, DOM) รจ uno standard ufficiale del W3C attraverso il quale la struttura di un documento (come ad esempio una pagina HTML) รจ rappresentata sotto forma di un modello orientato agli oggetti.

In pratica ogni elemento della struttura del documento รจ rappresentato sotto forma di nodo di un elemento padre creando una sorta di "albero" in cui si creano una serie di ramificazioni. facciamo un esempio partendo da una semplicissima struttura HTML:

Pubblicitร 
<html>
  <head>
    <title>titolo del documento</title>
  </head>
  <body>
    <h1>titolo H1</h1>
    <p>testo testo testo</p>
  </body>
</html>

La rappresentazione del DOM di questa pagina sarebbe:

  • documento
    • head
      • title
        • titolo del documento (text node)
    • body
      • h1
        • titolo H1 (text node)
      • p
        • testo testo testo (text node)

Il DOM e javascript

Attraverso Javascript รจ possibile manipolare il DOM della pagina; ogni elemento della pagina viene rappresentato come un oggetto il quale puรฒ essere manipolato attraverso metodi e proprietร .

Lโ€™oggetto di base per la manipolazione del DOM รจ document il quale rappresenta la radice del documento nel suo complesso (cioรจ la pagina web). Lโ€™oggetto document รจ il genitore di tutti gli altri elementi della pagina web.

Selezionare gli elementi della pagina

Attraverso lโ€™oggetto document รจ possibile accedere a tutti gli elementi della pagina. Per identificare il o gli elementi sui quali agire รจ necessario fare ricorso ad uno di questi metodi:

  • getElementByID() โ€“ identifica un solo elemento della pagina attraverso lโ€™attributo ID (univoco);
  • getElementByTagName() โ€“ identifica un set di elementi della pagina attraverso lโ€™indicazione dello specifico tag (ad esempio tutti i paragrafi o tutti i link);
  • getElementByClassName() โ€“ identifica un set di elementi della pagina attraverso lโ€™indicazione di una specifica classe;

Vediamo qualche esempio:

// identifico uno specifico elemento della pagina
var testo = document.getElementById('articolo');

// all'interno di questo elemento posso selezionare, ad esempio, tutti i link
var links = testo.getElementByTagName('a');

Come potete vedere ho applicato il metodo getElementById allโ€™oggetto document creando, a mia volta, un nuovo oggetto (che ho chiamato "testo"). In seguito ho applicato il metodo getElementByTagName al nuovo oggetto "testo" per identificare tutti i link presenti in quello specifico elemento della pagina.

Modificare lโ€™HTML del documento

Attraverso la proprietร  innerHTML posso "scrivere" codice HTML allโ€™interno di un qualsiasi nodo della pagina. Poco sopra, infatti, abbiamo visto come effettuare la selezione degli elementi e come, una volta selezionati, anche questi si trasformino in oggetti.

A questo punto non resta che applicare la proprietร  innerHTML allโ€™oggetto corrispondente al nodo il cui contenuto vogliamo modificare.

var testo = document.getElementById('articolo');
testo.innerHTML = 'Scrivo codice <b>HTML</b>...';

Cosรฌ facendo lโ€™eventuale contenuto dellโ€™elemento selezionato verrร  sostituito da quello specificato col metodo innerHTML.

Modificare il valore di un attributo

Nella lezione dedicata agli oggetti di javascript abbiamo accennato al fatto che ogni attributo si "trasforma" in una proprietร  dello specifico oggetto element a cui ri riferisce. Ne consegue che abbiamo la possibilitร  di manipolare gli attributi a nostro piacimento.

Si supponga, ad esempio, di voler cambiare lโ€™immagine sorgente (attributo src) di un tag <img>:

document.getElementById('miafoto').src = 'nuovafoto.jpg';

Modificare lo stile CSS di un elemento

Lโ€™attributo style di un oggetto element puรฒ diventare a sua volta un oggetto ed essere manipolato attraverso una serie di proprietร  corrispondenti alle proprietร  dei fogli di stile. vediamo un esempio:

// imposto il colore rosso per il testo
document.getElementById('articolo').style.color = '#FF0000';

Da notare che in Javascript i nomi di alcune proprietร  CSS variano leggermente quando vengono utilizzati sotto forma di proprietร . La proprietร  background-image, ad esempio, corrisponde alla proprietร  Javascript backgroundImage. In linea di massima possiamo dire che il nome delle proprietร  CSS composto da piรน parole separate dal trattino (come ad esempio "border-color") viene trasformato in una stringa unica in cui la parola che segue al trattino (che viene omesso) ha la prima lettera maiuscola (ad esempio "borderColor").

Gestire gli eventi utilizzando il DOM

Attraverso lโ€™utilizzo del DOM รจ anche possibile assegnare un evento ad un dato elemento della pagina. Ad esempio:

document.getElementById('miafoto').onclick = function(){ ... };

In questo caso lโ€™evento Javascript si trasforma in una proprietร  dellโ€™oggetto element e, come tale, puรฒ essere settato a piacimento.

Sempre attraverso il DOM รจ possibile creare degli event listener cioรจ dei "rilevatori di eventi" associati a specifici elementi della pagina. Facciamo un esempio:

// assegno una funzione esterna
foto.addEventListener('click', miafunzione);

// definisco internamente al metodo le istruzioni da eseguire
document.getElementById('miafoto').addEventListener('click', function() { alert('...'); });

Eโ€™ possibile associare una molteplicita di event handler (anche dello stesso tipo) a ciascun oggetto. Ad esempio, quindi, possiamo associare diverse funzioni al medesimo evento "click" sul medesimo oggetto con ID "miafoto".

var foto = document.getElementById('miafoto');
foto.addEventListener('click', miafunzione);
foto.addEventListener('click', suafunzione);
foto.addEventListener('click', tuafunzione);

Volendo รจ anche possibile compiere lโ€™operazione inversa, cioรจ disassociare una funzione da un dato evento su un oggetto. Per farlo si utilizza il metodo removeEventListener in questo modo:

foto.removeEventListener('click', tuafunzione);

Creare un nuovo elemento della pagina

Per aggiungere un nuovo elemento nellโ€™albero della pagina sarร  necessario prima crearlo e poi appenderlo al nodo nel quale o si desidera inserire. Per creare un nuovo elemento nel DOM si utilizza il metodo createElement() specificando, come attributo, che tipo di elemento si desidera creare. Una volta creato lโ€™elemento sarร , ovviamente, vuoto.

Nellโ€™esempio che segue, dopo aver creato un nuovo paragrafo, andremo a riempirlo creando un text-node al suo interno.

// creo il nuovo elemento (un paragrafo)
var nuovo = document.createElement('p');

// creo un nuovo nodo di testo per "riempire" il nuovo elemento
var testo = nuovo.createTextNode('Nuovo testo da inserire');

// appendo il nodo di testo al nuovo elemento
nuovo.appendChild(testo);

// seleziono il nodo nel quale voglio aggiungere il nuovo elemento
var articolo = document.getElementById('articolo');

// ora aggiungo il nuovo elemento al nodo selezionato all'inizio
articolo.appendChild(nuovo);

Utilizzando il metodo appendChild(), il nuovo elemento viene posizionato in fondo allโ€™elemento selezionato. Se non vogliamo che ciรฒ accada ma vogliamo inserire il nuovo elemento in un punto ben preciso abbiamo a disposizione il metodo insertBefore(). Questo metodo richiede due parametri: il primo corrisponde al nuovo elemento da inserire, il secondo corrisponde allโ€™oggetto che identifica il lโ€™elemento prima del quale effettuare lโ€™inserzione.

Si supponga, ad esempio, che il nostro articolo sia cosรฌ strutturato:

<div id="articolo">
  <p id="frase1">...</p>
  <p id="frase2">...</p>
  <p id="frase3">...</p>
</div>

e si supponga di voler inserire il nuovo paragrafo subito dopo il primo. Questo il codice del nostro esempio:

// creo il nuovo elemento (un paragrafo)
var nuovo = document.createElement('p');

// creo un nuovo nodo di testo per "riempire" il nuovo elemento
var testo = nuovo.createTextNode('Nuovo testo da inserire');

// appendo il nodo di testo al nuovo elemento
nuovo.appendChild(testo);

// seleziono il nodo nel quale voglio aggiungere il nuovo elemento
var articolo = document.getElementById('articolo');

// seleziono il sotto-elemento prima del quale voglio inserire quello nuovo 
var frase = articolo.getElementById('frase1');

// ora aggiungo il nuovo elemento al nodo selezionato subito prima dell'elemento "frase"
articolo.insertBefore(nuovo,frase);

Se al posto di insertBefore() avessimo utilizzato replaceChild() avremmo sostituito la frase con ID "frase1" con quella generata dinamicamente.

Eliminare un elemento dal DOM

Per eliminare un elemento dallโ€™albero del DOM si utilizza il metodo removeChild(). Come lascia intuire il nome, viene utilizzato per rimuovere un elemento figlio dellโ€™oggetto selezionato.

Volendo tornare allโ€™esempio visto sopra e supponendo di voler eliminare la frase con id "frase1" avremmo utilizzato il seguente codice:

// seleziono il nodo nel quale voglio lavorare
var articolo = document.getElementById('articolo');

// seleziono il sotto-elemento che desidero cancellare
var frase = articolo.getElementById('frase1');

// ora procedo all'eliminazione
articolo.removeChild(frase);

Una particolaritร  del DOM รจ che per rimuovere un elemento dalla pagina รจ sempre necessario conoscere lโ€™elemento genitore. Un "trucchetto" per ovviare a questa procedura รจ offerto da questo codice:

var elimina = document.getElementById('frase1');
elimina.parentNode.removeChild(elimina);

Muoversi tra gli elementi del DOM

Come abbiamo detto il DOM รจ come un albero rappresentato da diversi rami, ogni punto di origine di uno o piรน rami รจ detto nodo. Javascript disponde di diverse proprietร  per muoversi allโ€™interno dei vari nodi di un documento HTML. Questa sono:

  • parentNode
  • childNodes[indice]
  • firstChild
  • lastChild
  • nextSibling
  • previousSibling

Eโ€™ importante sottolineare che nel modello del DOM ogni blocco di testo corrisponde a un noto (Text Node) quindi per accedere, ad esempio, al testo contenuto allโ€™interno di una tag <p> sarร  necessario far riferimento ad un ulteriore nodo (il nodo di testo, appunto) e poi applicare la proprietร  nodeValue:

var testo = document.getElementById('frase1').firstChild.nodeValue;

In realtร , per raggiungere il nostro scopo, avremmo potuto scrivere piรน semplicemente:

var testo = document.getElementById('frase1').innerHTML;

Tuttavia era necessario sottolineare come, nel DOM, i blocchi di testo siano qualificati come nodi a se stanti.

parentNode

la proprietร  parentNode consente di accedere al nodo genitore dellโ€™oggetto element corrente.

Abbiamo giร  visto questa proprietร  allโ€™opera poco sopra, nellโ€™ultimo esempio relativo allโ€™eliminazione di un elemento dal DOM (cui vi invito a fare riferimento).

firstChild e lastChild

Queste tre proprietร  consentono di accedere, rispettivamente, al primo nodo e allโ€™ultimo elemento figlio dellโ€™oggetto element corrente.

childNodes

la proprietร  childNodes consente di accedere ad un determinato nodo figlio specificandone lโ€™indice numerico (ricordiamoci che la numerazione degli indici parte da 0 e NON da 1!).

In sostanza possiamo dire che childNodes[0] รจ lโ€™equivalente di firstChild.

nextSibling e previousSibling

Queste due proprietร  consentono di muoversi tra i nodi "fratelli" e piรน precisamente consento di accedere a quello precedente e quello successivo.

La radice del documento

Per accedere alla radice della nostra pagina HTML possiamo utilizzare la proprietร  documentElement dellโ€™oggetto document.

Se desideriamo selezionare solo il corpo del documento, invece, possiamo utilizzare semplicemente la proprietร  body.

var radice = document.documentElement;
var corpo = document.body;
Pubblicitร 
Massimiliano Bossi
Massimiliano Bossi
Stregato dalla rete sin dai tempi delle BBS e dei modem a 2.400 baud, ho avuto la fortuna di poter trasformare la mia passione in un lavoro (nonostante una Laurea in Giurisprudenza). Adoro scrivere codice e mi occupo quotidianamente di comunicazione, design e nuovi media digitali. Orgogliosamente "nerd" sono il fondatore di MRW.it (per il quale ho scritto centinaia di articoli) e di una nota Web-Agency (dove seguo in prima persona progetti digitali per numerosi clienti sia in Italia che all'estero).