function inserisci_frase() { if(document.getElementById && document.createTextNode) { frase = document.createTextNode("Iniziamo con un esempio semplice"); document.getElementById("par_pre").appendChild(frase); } else alert("metodo W3C non supportato"); }
function inserisci_immagine() { if(document.getElementsByTagName && document.createElement && document.getElementsByTagName("div").item(0).appendChild) { immagine = document.createElement("IMG"); immagine.setAttribute("src","https://static.html.it/app/uploads/documenti/guide/img/dom/dom_logo.gif"); document.getElementById("par_pre").appendChild(immagine); } else alert("metodo W3C non supportato") }
function rimuovi_frase() { if(this.frase) { document.getElementById("par_pre").removeChild(frase); frase = null; } }
function rimuovi_immagine() { if(this.immagine) { document.getElementById("par_pre").removeChild(immagine); immagine = null; } }
function inserisci_prima() { if(document.getElementsByTagName && document.createTextNode) { // prende per riferimento il contenitore della tabella div = document.getElementById("tabella_esempio"); // crea un nodo prefisso = document.createTextNode("Questa è la "); // cerca la seconda cella cella2 = div.getElementsByTagName("td").item(1); testo_esistente = cella2.firstChild; cella2.insertBefore(prefisso,testo_esistente); } else alert("metodo W3C non supportato"); }
function rimpiazza() { if(document.getElementsByTagName && document.createTextNode) { div = document.getElementById("tabella_esempio");
cella1 = div.getElementsByTagName("td").item(0); cella1.replaceChild(document.createTextNode("Testo rimpiazzato"),cella1.firstChild); } else alert("metodo W3C non supportato"); }
function modifica_nodo_testo() { if(document.getElementsByTagName) { div = document.getElementById("tabella_esempio"); div.getElementsByTagName("TD").item(0).firstChild.nodeValue = "Cambiamo il testo"; } else alert("metodo W3C non supportato"); }
function lista() { if(document.createTextNode && document.getElementsByTagName) { // Creiamo i nuovi Elementi Olist = document.createElement("ol"); voce1 = document.createElement("li"); voce2 = document.createElement("li"); testo1 = document.createTextNode("Prima creiamo gli elementi"); testo2 = document.createTextNode("Poi li inseriamo al volo nella pagina");
// Colleghiamoli tra loro in modo da formare // il nostro gruppo di elementi voce1.appendChild(testo1); voce2.appendChild(testo2); Olist.appendChild(voce1); Olist.appendChild(voce2);
// a questo punto lista contiene il riferimento // a tutto il gruppo di elementi. Ora non resta // che inserirli nel punto che desideriamo div = document.getElementById("lista_esempio");
testo_esistente = div.firstChild; div.insertBefore(Olist,testo_esistente); } else alert("metodo W3C non supportato"); }
function lista_piu() { if(document.createTextNode && document.getElementsByTagName) { // Creiamo i nuovi Elementi Olist = document.createElement("ol"); voce1 = document.createElement("li"); voce1.setAttribute("style","font-size:13px;"); voce1.setAttribute("class","classe_esempio_li"); under = document.createElement("strong"); voce1.appendChild(under); under.appendChild(document.createTextNode("Prima")); voce1.appendChild(document.createTextNode(" creiamo gli elementi"));
// ora invece di ripetere tutti questi passi, // sfruttiamo le potenzialità del metodo cloneNode e di replaceNode voce2 = voce1.cloneNode(true);
voce2.firstChild.replaceChild(document.createTextNode("Poi"),voce2.firstChild.firstChild); voce2.replaceChild(document.createTextNode(" li inseriamo al volo nella pagina"),voce2.childNodes[1]);
Olist.appendChild(voce1); Olist.appendChild(voce2);
div = document.getElementById("lista_esempio");
testo_esistente = div.firstChild; div.insertBefore(Olist,testo_esistente); } else alert("metodo W3C non supportato"); }
function lista_crossbrowser() { if(document.createTextNode && document.getElementsByTagName) { // Creiamo i nuovi Elementi Olist = document.createElement("ol"); voce1 = document.createElement("li"); voce1.setAttribute("class","classe_esempio_li");
// per Explorer (case-sensitive) voce1.setAttribute("className","classe_esempio_li");
voce1.style.fontSize = "14px";
under = document.createElement("strong"); voce1.appendChild(under); under.appendChild(document.createTextNode("Prima")); voce1.appendChild(document.createTextNode(" creiamo gli elementi"));
// ora invece di ripetere tutti questi passi, // sfruttiamo le potenzialità del metodo cloneNode e di replaceNode voce2 = voce1.cloneNode(true); voce2.firstChild.replaceChild(document.createTextNode("Poi"),voce2.firstChild.firstChild); voce2.replaceChild(document.createTextNode(" li inseriamo al volo nella pagina"),voce2.childNodes[1]);
Olist.appendChild(voce1); Olist.appendChild(voce2);
div = document.getElementById("lista_esempio");
testo_esistente = div.firstChild; div.insertBefore(Olist,testo_esistente); } else alert("metodo W3C non supportato"); }
function rem_lista_piu() { if(this.Olist) { this.Olist.parentNode.removeChild(Olist); Olist = null; } }
function rem_lista_cross() { if(this.crosslist) { this.crosslist.parentNode.removeChild(crosslist); crosslist = null; } }
Appendere e Rimuovere singoli Elementi
Occupiamoci ora di inserire nuovi nodi al documento HTML. Quello che andremo a fare è utilizzare i metodi per la creazione di nodi, dopodichè useremo i metodi per l'introduzione dei nodi in punti precisi della nostra pagina.
Cominciamo con qualcosa di semplice: supponiamo di voler creare un nuovo nodo di testo e di volerlo appendere alla fine del seguente paragrafo (tag <div>) il cui attributo id è "par_pre", il codice usato dalla funzione per l'inserimento del nodo di testo è il seguente:
function inserisci_frase() { if(document.getElementById && document.createTextNode) { // inanzitutto creiamo un nuovo nodo di testo frase = document.createTextNode("Iniziamo con un esempio semplice"); // poi, recuperiamo l'elemento con l'attributo ID pari "par_pre" // e appendiamoci il nodo di testo appena creato document.getElementById("par_pre").appendChild(frase); } }
Come l'esempio mostra e come spiegato nel corso della guida, il metodo appendChild() inserisce un nuovo nodo alla fine della lista dei figli del paragrafo "par_pre".
Inserire un nuovo nodo di testo è molto semplice, come lo è del resto, inserire qualsiasi altro elemento. Supponiamo di voler, ad esempio, inserire alla fine dello stesso paragrafo un'immagine. Il codice della funzione sarà :
function inserisci_immagine() { if(document.getElementById && document.createElement) { // Creiamo il nuovo elemento IMG e // impostiamo l'attributo src, che recupera l'immagine immagine = document.createElement("IMG") immagine.setAttribute("src","Logo.gif") immagine.setAttribute("alt","Esempio") // inseriamola quindi nel nostro paragrafo document.getElementById("par_pre").appendChild(immagine) } }
Lo stesso risultato lo potremmo ottenerlo, se fossimo certi che il paragrafo "par_pre", è il primo tag <pre> presente sulla pagina, e facendo quindi uso di getElementsByTagName.
function inserisci_immagine() { if(document.getElementsByTagName && document.createElement) { // Creiamo il nuovo elemento IMG e // impostiamo l'attributo src, che recupera l'immagine immagine = document.createElement("IMG"); immagine.setAttribute("src","/imagesg/linguaggi/dom_logo.gif"); // inseriamola quindi nel nostro tag <pre> document.getElementsByTagName("PRE").item(0).appendChild(immagine); } }
Nota: Bisogna fare molta attenzione nell'uso di questa tecnica, specie su pagine dinamiche dove i contenuti possono cambiare, potrebbe dare brutte sorprese. Non sempre infatti conosciamo il numero o l'ordine degli elementi di un certo tipo.
Provando e ricaricando la pagina, l'ordine con cui gli elementi sono inseriti in fondo al paragrafo riflette l'ordine cronologico che abbiamo usato nella pressione dei relativi pulsanti.
Questo evidenzia ancor meglio il comportamento sia del metodo appendChild()
, sia delle variabili globali (frase e immagine), che costituiscono un riferimento solo per l'ultimo elemento creato.
Perciò se ora volessimo rimuovere gli elementi inseriti, facendo riferimento alle variabili globali, il codice sarebbe:
function rimuovi_frase() { if(this.frase) { document.getElementById("par_pre").removeChild(frase); frase = null; } } function rimuovi_immagine() { if(this.immagine) { document.getElementById("par_pre").removeChild(immagine); immagine = null; } }
Eliminiamo solo gli ultimi elementi inseriti:
Nello snippet abbiamo fatto attenzione a controllare la presenza nello script delle variabili globali.
Inserire Singoli Elementi in maniera mirata
Appendere gli elementi in fondo alla lista dei figli di un nodo, non è l'unico modo per inserire nuove componenti all'interno di una pagina HTML. Esistono due metodi che consentono di incastonare liberamente gli elementi nel documento: insertBefore() e replaceChild().
Cominciamo a mostrare il loro funzionamento, facendo riferimento alla tabella che vedete oltre il codice. Inseriamo un nuovo nodo di testo nella seconda cella della tabella, appena prima del testo gia presente.
Per non incorrere in brutte sorprese facciamo le ricerche in un elemento specifico che fa da contenitore. Lo delimitiamo con il tag <div> e gli assegnamo id="tabella_esempio" Il codice è:
function inserisci_prima() { if(document.getElementsByTagName && document.createTextNode) { // prende per riferimento il contenitore della tabella div = document.getElementById("tabella_esempio"); // crea un nodo prefisso = document.createTextNode("Questa è la "); // cerca la seconda cella cella2 = div.getElementsByTagName("TD").item(1); testo_esistente = cella2.firstChild; cella2.insertBefore(prefisso,testo_esistente); } else alert("metodo W3C non supportato"); }
cella 1 | cella 2 |
cella 3 | cella 4 |
A questo punto possiamo rimpiazzare un nodo già esistente con uno che creiamo noi. Consideriamo il seguente codice:
function rimpiazza() { if(document.getElementsByTagName && document.createTextNode) { // Creiamo il nuovo nodo di testo e rimpiazziamolo // ad uno gia esistente (quello nella prima cella) // usando una sintassi un po' più compatta div = document.getElementById("tabella_esempio"); cella1 = div.getElementsByTagName("td").item(0); cella1.replaceChild(document.createTextNode("Testo rimpiazzato"),cella1.firstChild); // è equivalente a: /* ------------------------------------------------ cella1 = div.getElementsByTagName("td").item(0); nuovo_nodo = document.createTextNode("Testo rimpiazzato"); cella1.replaceChild(nuovo_nodo,cella1.firstChild); ------------------------------------------------- */ } }
In questo caso, nel quale rimpiazziamo un nodo di testo esistente, con uno nuovo, possiamo anche sfruttare la proprietà nodeValue
, che ci permette di modificare il nodo di testo esistente. Il codice diventa ancor più semplice:
function modifica_nodo_testo() { if(document.getElementsByTagName) { div = document.getElementById("tabella_esempio"); cella1 = div.getElementsByTagName("TD").item(0); cella1.firstChild.nodeValue = "Cambiamo il testo"; } }
Inserire e Rimuovere gruppi di Elementi
Cominciamo adesso a vedere come inserire più elementi in una sola volta, creando i presupposti per la creazione di vere e proprie pagine dinamiche.
Non perdiamoci in chiacchiere e passiamo a qualche esempio concreto. Supponiamo di inserire al volo un'intera lista di voci. I passi da seguire sono gli stessi visti negli esempi precedenti: creare gli elementi che comporranno la nostra lista e inserirli poi nel punto che desideriamo della pagina:
function lista() { if(document.createTextNode && document.getElementsByTagName) { // Creiamo i nuovi Elementi Olist = document.createElement("ol"); voce1 = document.createElement("li"); voce2 = document.createElement("li"); testo1 = document.createTextNode("Prima creiamo gli elementi"); testo2 = document.createTextNode("Poi li inseriamo al volo nella pagina"); // Colleghiamoli tra loro in modo da formare // il nostro gruppo di elementi voce1.appendChild(testo1); voce2.appendChild(testo2); Olist.appendChild(voce1); Olist.appendChild(voce2); // a questo punto lista contiene il riferimento // a tutto il gruppo di elementi. Ora non resta // che inserirli nel punto che desideriamo div = document.getElementById("lista_esempio"); testo_esistente = div.firstChild; div.insertBefore(Olist,testo_esistente); } else alert("metodo W3C non supportato"); }
Complichiamo un pochino le cose. Inseriamo una formattazione per il testo all'interno delle voci della lista e applichiamo uno stile in linea e una classe di stile ai tag <li>
:
function lista_piu() { if(document.createTextNode && document.getElementsByTagName) { // Creiamo i nuovi Elementi Olist = document.createElement("ol"); voce1 = document.createElement("li"); voce1.setAttribute("style","font-size:13px;"); voce1.setAttribute("class","classe_esempio_li"); under = document.createElement("strong"); voce1.appendChild(under); under.appendChild(document.createTextNode("Prima")); voce1.appendChild(document.createTextNode(" creiamo gli elementi")); // ora invece di ripetere tutti questi passi, // sfruttiamo le potenzialità del metodo cloneNode e di replaceNode voce2 = voce1.cloneNode(true); voce2.firstChild.replaceChild(document.createTextNode("Poi"),voce2.firstChild.firstChild); voce2.replaceChild(document.createTextNode(" li inseriamo al volo nella pagina"),voce2.childNodes[1]); Olist.appendChild(voce1); Olist.appendChild(voce2); div = document.getElementById("lista_esempio"); testo_esistente = div.firstChild; div.insertBefore(Olist,testo_esistente); } else alert("metodo W3C non supportato"); }
Testando quest'ultimo esempio su più browser, i risultati sono differenti. In particolare solo Netscape 6.0 esegue alla lettera tutte le istruzioni applicando la classe di stile e lo stile in linea ad entrambe le voci della lista creata.
Mozilla 1.0, non duplica sull'elemento clonato lo stile in linea, questo perché, in realtà , style
non è un vero e proprio attributo in accordo con il DOM, ma più che altro "un'estensione" dell'oggetto style
, che viene compresa e correttamente elaborata, ma non clonata.
Infatti il metodo cloneNode clona il nodo con tutti i suoi attributi e, eventualmente, tutti i suoi figli, e style
così definito, non ricade né nell'una né nell'altra specie.
Explorer 6.0 ignora completamente entrambi gli attributi style
e class
.
Per definire gli stili, conviene usare la sintassi standard relativa all'oggetto style, perciò invece di settare l'attributo style (che, per cosଠdire, è una forzatura dell'oggetto style), scriveremo:
voce1.style.fontSize = "19px";
Utilizzando questa sintassi, lo stile verrà clonato insieme all'oggetto style, sul nuovo nodo "voce2".
Possiamo sistemare le cose anche per quanto riguarda l'assegnazione di classi in Explorer. Infatti IE consente di attribuire classi di stile anche ai nuovi elementi creati, attraverso l'uso dell'attributo non standard className
(l'attributo è case sensitive). Per cui, per far accettare la classe anche ad Explorer dovremmo aggiungere la riga:
voce1.setAttribute("className","classe_esempio_li");
A questo punto il codice corretto sarà :
function lista_crossbrowser() { if(document.createTextNode && document.getElementsByTagName) { // Creiamo i nuovi Elementi Olist = document.createElement("ol"); voce1 = document.createElement("li"); voce1.setAttribute("class","classe_esempio_li"); // per Explorer (case-sensitive) voce1.setAttribute("className","classe_esempio_li"); voce1.style.fontSize = "14px"; under = document.createElement("strong"); voce1.appendChild(under); under.appendChild(document.createTextNode("Prima")); voce1.appendChild(document.createTextNode(" creiamo gli elementi")); // ora invece di ripetere tutti questi passi, // sfruttiamo le potenzialità del metodo cloneNode e di replaceNode voce2 = voce1.cloneNode(true); voce2.firstChild.replaceChild(document.createTextNode("Poi"),voce2.firstChild.firstChild); voce2.replaceChild(document.createTextNode(" li inseriamo al volo nella pagina"),voce2.childNodes[1]); Olist.appendChild(voce1); Olist.appendChild(voce2); div = document.getElementById("lista_esempio"); testo_esistente = div.firstChild; div.insertBefore(Olist,testo_esistente); } else alert("metodo W3C non supportato"); }
Explorer permette di impostare gli stili in linea anche utilizzando la proprietà cssText
(cosa non concessa negli altri browser dove la proprietà è di sola lettura):
voce1.style.cssText="{font-size:19px;}"
In questo modo è possibile impostare tutti gli stili in una singola riga. È però consigliabile utilizzare l'oggetto style
per inserire stili in linea, per questioni di compatibilità crossbrowser.
L'operazione di rimozione di gruppi di elementi ha la medesima difficoltà dell'operazione di rimozione di un singolo elemento:
function rem_lista_piu() { if(this.Olist) { document.getElementsByTagName("lista_esempio").removeChild(Olist); Olist = null; } }