DOM sta per modello ad oggetti del documento, è un termine che si descrive da solo: fornisce un modello ad oggetti relativo a un documento HTML. Il DOM Inspector integrato in Mozilla mostra le parti coinvolte ei nodi di terminazione in una gerarchia ad albero. Naturalmente l’ API del DOM non supporta solo i metodi per accedere agli elementi nell’ albero del DOM ma anche per aggiungere e rimuovere elementi. Rimane un quesito: è meglio utilizzare un oggetto del DOM oppure qualche tradizionale oggetto JavaScript come form o images? Naturalmente il DOM è molto più flessibile, ma talvolta può anche essere molto più complicato.
ACCEDERE A SPECIFICI ELEMENTI
Document.getElementById(“para”)
Quando lavorate con il DOM il modo ideale per accedere successivamente a un elemento della paginas è attribuirgli un identificatore univoco o ID. Successivamente il metodo DOM document.getElementById() accede a quel dato elemento e vi consente di partire da quel punto: modificare l’elemento, aggiungere sottoelementi, o altrimenti navigare nell’ albero DOM. Nell’ esempio seguente ai accede all’ elemento P. In funzione del browser la stringa che rappresenta la chiave dell’ elemento è differente. Mentre Internet Explorer restituisce semplicemente object i browser Mozilla sono più verbosi: object HTMLParagraphElement:
<script language=”JavaScript” type=”text/javascript”>
window.onload = function() {
window.alert(document.getElementById(”para”));
}
</script>
<p id=”para”>JavaScript Phrasebook</p>
ACCEDERE AI MARCATORI
Document.getElementByTagName(“p”)
Un modo alternativo per accedere agli elementi della pagina corrente è attraverso i nomi dei marcatori. Si può usare il metodo document.getElementsByTagName() una volta fornito il nome del marcatore otterrò un array di tutti i marcatori che posso processare per successivi utilizzi:
<script language=”JavaScript” type=”text/javascript”>
window.onload = function() {
window.alert(
document.getElementsByTagName(”p”) +
” (” + document.getElementsByTagName(”p”).length + ” elements)”);
}
</script>
<p>JavaScript Phrasebook</p>
<p>Sams Publishing</p>
[Il risultato di questo codice è object HTMLCollection] 2 elements. Internet Explorer nuovamente restituisce meno informazioni, mostrando [object] (2 elements)
NAVIGARE L’ALBERO DOM
Una volta che siete all’ interno del DOM potete navigarne la struttura, andando in alto e in basso a sinistra e a destra. Ecco una lista delle più importanti proprietà che possiede ogni nodo DOM
firstChild: nodo primo figlio
lastChild:nodo ultimo figlio
childNodes: tutti i nodi figli come array
parentNode: nodo genitore
nextSibling: sono successivo sullo stesso livello (alla destra)
prevoiousSibling:nodo precedente sullo stesso livello (“alla sinistra”)
Inoltre nodeName restituisce il nome del marcatore del nodo (o #text per i nodi di testo), invece nodeValue restituisce il valore di un nodo (utile con un nodo di testo)
DETERMINARE LE INFORMAZIONI SUL NODO
Il codice che segue analizza una semplice struttura DOM e restituisce le informazioni riguardanti tutti i nodi figli. Verranno messi diversi tipi di nodo contrassegnati da un numero identificativo: 1 sta per marcatore/ 2 attributo/3 testo/8 commento HTML/9 Documento/10 DTD/11 Frammento
<script language=”JavaScript” type=”text/javascript”>
window.onload = function() {
var s = “”;
with (document.getElementById(”para”)) {
for (var i=0; i<childNodes.length; i++) {
with (childNodes[i]) {
s += nodeName + “: ” + nodeValue + ” (” + nodeType + “)\n”;
}
}
}
window.alert(s);
}
</script>
<p id=”para”><em>JavaScript</em> Phrasebook</p>
<script language=”JavaScript” type=”text/javascript”>
function removeItem() {
var list = document.getElementById(”list”);
if (list.childNodes.length > 0) {
list.removeChild(list.lastChild);
}
}
</script>
<ol id=”list”><li>Item</li><li>Item</li><li>Item</li><li>Item</li></ol>
<input type=”button” onclick=”removeItem();” value=”Remove item” />
RIMUOVERE ELEMENTI
list.removeChild(list.lastChild);
il metodo removeChild() che ogni nodo possiede, può essere utilizzato per rimuovere un nodo dell’ albero DOM. Si noti che dovete chiamare questo metodo dall’ elemento genitore del nodo da eliminare e fornire il nodo come parametro.
<script language=”JavaScript” type=”text/javascript”>
function removeItem() {
var list = document.getElementById(”list”);
if (list.childNodes.length > 0) {
list.removeChild(list.lastChild);
}
}
</script>
<ol id=”list”><li>Item</li><li>Item</li><li>Item</li><li>Item</li></ol>
<input type=”button” onclick=”removeItem();” value=”Remove item” />
Quando avete accesso diretto solo al nodo da eliminare (curNode nel codice che segue) funzionerà anche l’approccio seguente:
curNode.parentNode.removeChild(curNode);
quando chiamate questo codice in una funzione di gestione relativa al nodo stesso, potete sostituire curNode con this
AGGIUNGERE ELEMENTI
List.appendChild(newNode);
Si creano nuovi nodi DOM con il metodo document.createElement(). Questo crea un nuovo elemento, utilizzando il nome del marcatore fornito come parametro. Poi questo elemento può essereinserito nell’ albero DOM. Il metodo (node) utilizzato spesso è appendChild(), che aggiunge un nuovo figlio alla fine dell’ elenco dei figli. Il codice seguente aggiunge una nuova, vuota, voce di elenco (<li>) alla fine dell’ elenco <ul> ogni volta che si fa click sul pulsante:
<script language=”JavaScript” type=”text/javascript”>
function addItem() {
var list = document.getElementById(”list”);
var newNode = document.createElement(”li”);
list.appendChild(newNode);
}
</script>
<ul id=”list”><li>Item</li></ul>
<input type=”button” onclick=”addItem();” value=”Add item” />
Lo svantaggio di questo approccio è che il nuovo element viene sempre aggiunto alla fine dell’ elenco dei figli. Per alleviare questo difetto, il metodo insertBefore() consente di inserire un nodo prima di ogni altro nodo (quindi potete inserirlo ovunque, eccetto che alla fine dell’ elenco, avete sempre appendChild() allo scopo). Come parametri fornite prima il nuovo nodo, poi il nuovo fratello. Il codice che segue inserisce un nuovo elemento <li> all’ inizio dell’ elenco ogni volta che si fa clic sul pulsante.
<script language=”JavaScript” type=”text/javascript”>
function addItem() {
var list = document.getElementById(”list”);
var newNode = document.createElement(”li”);
list.insertBefore(newNode, list.firstChild);
}
</script>
<ul id=”list”><li>Item</li></ul>
<input type=”button” onclick=”addItem();” value=”Add item” />
CREARE ELEMENTI DI TESTO
Var newTextNode= document.createTextNode(“Item “ + nr);
Se volete inserire del testo in un elemento, avete bisogno di un nodo di testo che è un sottonodo del nodo di un elemento vero e proprio. Il metodo createTetNode() crea tale nodo di testo, voi fornite solo il testo effettivo.Nel codice seguente aggiungiamo voci di elenco, che tuttavia hanno questa volta del testo. Quinbdi prima create un nodo di testo , poi aggiungete questo nodo di testo a un altro nodo (il quale poi potrebbe essere aggiunto a un altro nodo etc etc)
<script language=”JavaScript” type=”text/javascript”>
var nr = 1;
function addItem() {
var list = document.getElementById(”list”);
var newNode = document.createElement(”li”);
nr++;
var newTextNode = document.createTextNode(”Item ” + nr);
newNode.appendChild(newTextNode);
list.appendChild(newNode);
}
</script>
<ul id=”list”><li>Item 1</li></ul>
<input type=”button” onclick=”addItem();” value=”Add item” />
LAVORARE CON GLI ATTRIBUTE
newLink.setAttribute(“href”, http://www.samspublishing.com/);
Finora gli esempi di questo libro hanno trattato sia di i marcatori che i nodi di testo. Mancano solo gli attributi. Potete accedere agli attributi sotto forma di nodi ma il modo più conveniente è utilizzare il metodo setAttribute(); dovete semplicemente fornire il nome dell’ attributo e il suo valore.
<script language=”JavaScript” type=”text/javascript”>
var nr = 1;
function addItem() {
var list = document.getElementById(”list”);
var newNode = document.createElement(”li”);
var newLink = document.createElement(”a”);
newLink.setAttribute(”href”, “http://www.samspublishing.com/”);
nr++;
var newTextNode = document.createTextNode(”Item ” + nr);
newLink.appendChild(newTextNode);
newNode.appendChild(newLink);
list.appendChild(newNode);
}
</script>
<ul id=”list”><li>Item 1</li></ul>
<input type=”button” onclick=”addItem();” value=”Add item” />
CLONARE ELEMENTI

Var newItem = oldItem.cloneNode(true);
Invece di creare in continuazione nuovi nodi potete anche clonare un nodo esistente. Il metodo clodeNode(), che ogni nodo possiede, fa questo per voi. Potete decidere se clonare solo il nodo e i suoi attributi, oppure clonare anche tutti i nodi figli (e i figli dei loro figli e così via). Se come parametro di cloneNode() fornite true effettuate una cosiddetta copia profonda, copia anche i figli; false copia invece solo il nodo.
<script language=”JavaScript” type=”text/javascript”>
var nr = 1;
function addItem(cloneMode) {
var list = document.getElementById(”list”);
var oldItem = list.firstChild;
var newItem = oldItem.cloneNode(cloneMode);
list.appendChild(newItem);
}
</script>
<ul id=”list”><li><a href=”http://www.samspublishing.com/”>Item 1</a></li></ul>
<input type=”button” onclick=”addItem(true);” value=”Clone all” />
<input type=”button” onclick=”addItem(false);” value=”Clone node only” />
SOSTITUIRE ELEMENTI

List.replaceChild(newNode, list.firstChild);
Se rimuovete un nodo e poi ne inserite un altro nello stesso post oil metodo replaceChild() vi farà risparmiare un bel pò di codice. Voi fornite il nuovo e vecchio nodo e Java Script farà il resto per voi. Ricordatevi che dovete chiamare questo metodo dall’ elemento genitore del vecchio e del nuovo nodo!
<script language=”JavaScript” type=”text/javascript”>
var nr = 1;
function addItem() {
var list = document.getElementById(”list”);
var newNode = document.createElement(”li”);
nr++;
var newTextNode = document.createTextNode(”Item ” + nr);
newNode.appendChild(newTextNode);
list.replaceChild(newNode, list.firstChild);
}
</script>
<ul id=”list”><li>Item 1</li></ul>
<input type=”button” onclick=”addItem();” value=”Replace item” />
Il codice precedente rimpiazza il primo figlio (nodo) dall’ elenco con un nuovo nodo.
CREARE UN ELENCO DI DATI PUNTATI IN JAVA SCRIPT
Var newItem = document.createElement(“li”);
Var newText = document.createTextNode(data[i]);
newItem.appendChild(newText);
list.appendChild(newItem);
specie in contesti con Web Service e Ajax spesso riceverete dei dati dal server e dovrete mostrarli in modo dinamico. Un buon approccio è usare un elenco HTML. Il codice seguente fornisce una funzione createList() che aspetta un array con dei valori e li converte in un elenco:
<script language=”JavaScript” type=”text/javascript”>
function createList(data) {
var list = document.createElement(”ul”);
for (var i = 0; i < data.length; i++) {
var newItem = document.createElement(”li”);
var newText = document.createTextNode(data[i]);
newItem.appendChild(newText);
list.appendChild(newItem);
}
return list;
}
window.onload = function() {
var list = createList(["one", "two", "three", "four", "five"]);
document.body.appendChild(list);
}
</script>
Si noti che document.body è u na scorciatoia dell’ elemento <body> (altrimenti potreste utilizzare document.getElementByTagName(“body”)[0]); poi appendChild() aggiunge l’elenco HTML aqlla fine della pagina
CREARE UNA TABELLA DI DATI IN JAVA SCRIPT

var td = document.createElement(”td”);
var newText = document.createTextNode(data[i][j]);
td.appendChild(newText);
tr.appendChild(td);
una intera tabella è un po’ più complicata di un elenco. Dapprima dovete usare l’elemento tbody (potreste voler utilizzare anche <thead> e o <tfoot>. La funzione di aiuto createTable() si aspetta un array multidimensionale. Ogni elemento dell’ array in se stesso è un elenco di valori da mostrare nella tabella; il primo elemento dell’ array contiene il testo dell’ intestazione di ciascuna colonna. Come potete vedere il codice è più lungo, ma d’altro canto l’approccio di base è il medesimo: creare nodi e nodi di testo e concatenarli gli agli altri nel giusto ordine. Ecco il codice risultante:
<script language=”JavaScript” type=”text/javascript”>
function createTable(data) {
var table = document.createElement(”table”);
var thead = document.createElement(”thead”);
var tr = document.createElement(”tr”);
for (var i = 0; i < data[0].length; i++) {
var th = document.createElement(”th”);
var newText = document.createTextNode(data[0][i]);
th.appendChild(newText);
tr.appendChild(th);
}
thead.appendChild(tr);
table.appendChild(thead);
var tbody = document.createElement(”tbody”);
for (var i = 1; i < data.length; i++) {
var tr = document.createElement(”tr”);
for (var j=0; j < data[i].length; j++) {
var td = document.createElement(”td”);
var newText = document.createTextNode(data[i][j]);
td.appendChild(newText);
tr.appendChild(td);
}
tbody.appendChild(tr);
}
table.appendChild(tbody);
return table;
}
window.onload = function() {
var table = createTable([
["1", "2", "3", "4", "5"],
["one", "two", "three", "four", "five"],
["un", "deux", "trois", "quatre", "cinq"],
["eins", "zwei", "drei", "vier", "fünf"]]);
document.body.appendChild(table);
}
</script>
MODIFICARE FRAMMENTI DI CODICE HTML
list.innerHTML += newNode;
Modificare nodi di testo (o sostituendoli utilizzando la proprietà nodeValue) modifica solo il testo effettivo, ma non modifica interi frammenti di codice HTML, compresi sottoelementi. Per far questo risulta utile la proprietà innerHTML di tutti gli elementi. Nonostante innerHTML non sia uno standard e non sia parte di nessuna specifica DOM, funziona bene. Con innerHTML, potete cambiare il codice HTML interno di ogni elemento HTMl e anche inserire nuovi sottoelementi. Come mostrato dal listato:
<script language=”JavaScript” type=”text/javascript”>
var nr = 1;
function addItem() {
var list = document.getElementById(”list”);
nr++;
var newNode = “<li>Item ” + nr + “</li>”;
list.innerHTML += newNode;
}
</script>
<ul id=”list”><li>Item 1</li></ul>
<input type=”button” onclick=”addItem();” value=”Add item” />
innerHTML scrive il codice HTMl dentro un elemento
POSIZIONARE GLI ELEMENTI
el.style.left = “0px”;
el.style.posLeft = 0;
el.style.top = “0px”;
el.style.posTop = 0;
i css supportano il posizionamento degli elementi: in particolare il posizionamento assoluto e il posizionamento relativo. Non ha importanza quale metodo scegliete, con JavaScript potete impostare i valori di posizionamento. In genere il posizionamento assoluto è più comodo perché così non dovete calcolare il posizionamento degli elementi nidificati. In gran parte dei browser la proprietà left definisce la coordinata x dell’ elemento e la proprietà top è usata per la coordinata y. I valori non sono numerici, ma di norma come prevede il copione css, comprendono una unità, in genere pixel.
Con Internet Explorer avete bisogno di un altro approccio. Le proprietà posLeft e posTop impostano la posizione orizzontale e verticale; tuttavia questa volta fornite un valore numerico non una unità. La strategia più pratica è impostare tutte queste proprietà, visto che non hanno effetti collaterali. Ciò vi evita il rilevamento dei browser. Il seguente codice posiziona l’elemento <div> nell’ angolo superiore sinistro, si noti che adesso tale elemento si sovrappone aql testo della pagina:
<script language=”JavaScript” type=”text/javascript”>
function position() {
var el = document.getElementById(“element”);
el.style.left = “0px”;
el.style.posLeft = 0;
el.style.top = “0px”;
el.style.posTop = 0;
}
window.onload = position;
</script>
<h1>My Portal</h1>
<p>Some sample text. Some sample text. Some sample text.
Some sample text. Some sample text. Some sample text.
Some sample text. Some sample text. Some sample text.
Some sample text. Some sample text. Some sample text. </p>
<div id=”element” style=”position: absolute; background-color: #eee; border: 1px solid”>
JavaScript Phrasebook
</div>
ANIMARE UN ELEMENTO
Id= window.setInterval(“animate();”,100);
un effetto dhtml piuttosto raro, ma ancora utilizzato è non solo posizionare ma anche muovere e dunque animare un elemento. Per farlo risultano pratici window.setTimeout() e window.setInterval(). Il codice che segue anima un banner pubblicitario in diagonale sull pagina. Il problema è come animare la posizione. Per le proprietà (posLeft, posTop) di Internet Explorer basta ggiungere un valore. Per left e top, prima dovete determinare la vecchia posizione poi aggiungere un valore ad essa. La funzione JavaScript parseInt() estrae il contenuto numerico di una stringa come “123px”. Tuttavia parseInt() restituisce NaN se non trova nessun valore per left e top. Quindi la seguente funzione di aiuto si occupa di questa situazione; in questo caso invece, resistuirà 0;
function myParseInt(s) {
var ret= parseInt(s);
return (isnan(ret) ? 0 : ret);
}
Quindi il codice seguente anima il banner e si firma dopo 50 ripetizioni:
<script language="JavaScript" type="text/javascript">
var nr = 0;
var id = null;
function myParseInt(s) {
var ret = parseInt(s);
return (isNaN(ret) ? 0 : ret);
}
function animate() {
nr++;
if (nr > 50) {
window.clearInterval(id);
document.getElementById("element").style.visibility = "hidden";
} else {
var el = document.getElementById("element");
el.style.left = (myParseInt(el.style.left) + 5) + "px";
el.style.posLeft += 5;
el.style.top = (myParseInt(el.style.top) + 5) + "px";
el.style.posTop += 5;
}
}
window.onload = function() {
id = window.setInterval("animate();", 100);
};
</script>
<h1>My Portal</h1>
<p>Some sample text. Some sample text. Some sample text.
Some sample text. Some sample text. Some sample text.
Some sample text. Some sample text. Some sample text.
Some sample text. Some sample text. Some sample text. </p>
<div id="element" style="position: absolute; background-color: #eee; border: 1px solid">
JavaScript Phrasebook
</div>
CREARE UNA BARRA DI NAVIGAZIONE PERSISTENTE

window.onload = positionNavigation;
window.onscroll = positionNavigation;
A volte è importante che una parte della pagina sia sempre visibile. In funzione della natura del sito questa può essere un banner pubblicitario o una barra di navigazione. Ancora una volta posizioniamo un elemento div. La caratteristica particolare di una barra di navigazione persistente è che essa sta nella stessa posizione anche se l’utente scorre la pagina. Dunque il codice precedente è utilizzato per richiamare il posizionamento sia quando la pagina carica, sia quando essa scorre. Per calcolare la nuova posizione, dovete calcolare l’attuale scorrimento della pagina. Internet Explorer lo fa con document.bosy.scrollLeft e document.body.scrollTop; gli altri browser usano window.pageXOffset e window.pageYOffset. Il codice seguente mantiene fissa la posizione della barra di navigazione:
<script language="JavaScript" type="text/javascript">
function positionNavigation() {
var nav = document.getElementById("navigation");
var x, y;
var navwidth = 155;
if (window.innerWidth) {
x = window.innerWidth + window.pageXOffset - navwidth;
y = window.pageYOffset + 10;
} else {
with (document.body) {
x = clientWidth + scrollLeft - navwidth;
y = scrollTop + 10;
}
}
nav.style.left = x + "px";
nav.style.posLeft = x;
nav.style.top = y + "px";
nav.style.posTop = y;
}
window.onload = positionNavigation;
window.onscroll = positionNavigation;
</script>
<h1>My Portal</h1>
<p>Some sample text. Some sample text. Some sample text.
Some sample text. Some sample text. Some sample text.
Some sample text. Some sample text. Some sample text.
Some sample text. Some sample text. Some sample text. </p>
<p>Some sample text. Some sample text. Some sample text.
Some sample text. Some sample text. Some sample text.
Some sample text. Some sample text. Some sample text.
Some sample text. Some sample text. Some sample text. </p>
<p>Some sample text. Some sample text. Some sample text.
Some sample text. Some sample text. Some sample text.
Some sample text. Some sample text. Some sample text.
Some sample text. Some sample text. Some sample text. </p>
<p>Some sample text. Some sample text. Some sample text.
Some sample text. Some sample text. Some sample text.
Some sample text. Some sample text. Some sample text.
Some sample text. Some sample text. Some sample text. </p>
<p>Some sample text. Some sample text. Some sample text.
Some sample text. Some sample text. Some sample text.
Some sample text. Some sample text. Some sample text.
Some sample text. Some sample text. Some sample text. </p>
<div id="navigation" style="position: absolute; background-color: #eee; border: 1px solid">
<a href="http://www.samspublishing.com/">Sams Publishing</a><br />
<a href="http://www.amazon.com/gp/product/0672328801">This book at Amazon</a><br />
<a href="http://www.hauser-wenz.de/blog/">Author's weblog</a>
</div>