W3docs

Proprietà dei nodi: tipo, tag e contenuto

Padroneggiare il DOM è fondamentale per ogni sviluppatore web. Questo articolo esplora le proprietà principali dei nodi: tipo, tag e contenuto.

Ogni nodo nell'albero DOM è un object JavaScript, e quell'object espone proprietà che indicano che tipo di nodo è, quale tag rappresenta e quale contenuto contiene. Una volta che sai leggere queste proprietà con sicurezza, navigare e modificare una pagina diventa molto meno soggetto a errori. Questo capitolo tratta la gerarchia di classi dei nodi, le proprietà di tipo e nome (nodeType, nodeName, tagName) e le quattro proprietà di contenuto che utilizzerai quotidianamente (textContent, innerHTML, outerHTML e nodeValue/data) — incluso quando ciascuna è sicura da usare.

Se non hai ancora visto come il DOM è strutturato come albero, leggi prima Capire i nodi del DOM.

La gerarchia di classi dei nodi

Gli object DOM non condividono tutti lo stesso insieme di proprietà. Sono organizzati in una gerarchia di classi, in cui ogni classe aggiunge funzionalità a quella superiore:

  • Node — la classe base. Ogni nodo (elemento, testo, commento, documento) eredita da essa. Fornisce proprietà generiche come nodeType, nodeName, nodeValue, parentNode e childNodes.
  • Element — un nodo che è un tag. Aggiunge tagName, innerHTML, attributi, children e metodi di ricerca.
  • HTMLElement — la base per ogni elemento HTML concreto. Sottoclassi come HTMLInputElement, HTMLAnchorElement e HTMLTableElement aggiungono proprietà specifiche del tag (ad es. input.value, a.href).
  • Text e Comment — nodi foglia che contengono testo. Ereditano da CharacterData, che aggiunge la proprietà data.

Conoscere questa gerarchia spiega perché un <div> ha innerHTML ma un nodo di testo no: innerHTML appartiene a Element, e un nodo di testo non è un elemento. Puoi verificare la classe di un object con Object.prototype.toString o il nome del costruttore:

const div = document.createElement('div');
console.log(div.constructor.name);          // "HTMLDivElement"
console.log(div instanceof HTMLElement);    // true
console.log(div instanceof Element);        // true
console.log(div instanceof Node);           // true

Tipi e nomi dei nodi

Tipi di nodi (nodeType)

La proprietà nodeType è un intero che identifica la categoria di un nodo. È di sola lettura ed è il modo più affidabile per gestire la logica durante l'attraversamento del DOM, perché i nodi di testo e i nodi commento si confondono facilmente con gli elementi. I valori più comuni sono:

  • 1 — Nodo elemento (Node.ELEMENT_NODE): un tag HTML o XML come <div> o <p>.
  • 2 — Nodo attributo (Node.ATTRIBUTE_NODE): legacy; il codice moderno legge gli attributi con getAttribute()/setAttribute() invece di navigare i nodi attributo.
  • 3 — Nodo testo (Node.TEXT_NODE): il testo tra i tag, inclusi spazi bianchi e interruzioni di riga.
  • 8 — Nodo commento (Node.COMMENT_NODE): un commento HTML <!-- ... -->.
  • 9 — Nodo documento (Node.DOCUMENT_NODE): l'object document stesso, la radice dell'albero.

Preferisci le costanti con nome ai numeri grezzi — sono più leggibili e non cambiano mai:

const div = document.createElement('div');
div.textContent = 'Hello';

console.log(div.nodeType);                          // 1
console.log(div.nodeType === Node.ELEMENT_NODE);    // true

const textNode = div.firstChild;
console.log(textNode.nodeType === Node.TEXT_NODE);  // true

<!-- snippet: html-result -->

<div id="example">Example node</div>
<script>
    const node = document.getElementById("example");
    node.innerHTML = 'Node type is: ' + node.nodeType;
</script>

Nomi dei nodi: nodeName vs tagName

Entrambe le proprietà restituiscono il nome di un nodo, ma differiscono per ambito:

  • nodeName esiste su ogni nodo. Per un elemento restituisce il nome del tag; per un nodo di testo restituisce "#text"; per un commento, "#comment"; per il documento, "#document".
  • tagName esiste solo sugli elementi. Su un nodo non-elemento vale undefined.

Per i documenti HTML, entrambe restituiscono il nome del tag in maiuscolo ("DIV", non "div"), indipendentemente da come hai scritto il tag:

const div = document.createElement('div');
console.log(div.nodeName);             // "DIV"
console.log(div.tagName);              // "DIV"

const textNode = document.createTextNode('hi');
console.log(textNode.nodeName);        // "#text"
console.log(textNode.tagName);         // undefined

Regola pratica: usa tagName quando sai già di avere a che fare con un elemento; usa nodeName quando potresti ispezionare qualsiasi tipo di nodo.

<!-- snippet: html-result -->

<div id="example"></div>
<script>
    const element = document.getElementById('example');
    element.innerHTML = 'nodeName: ' + element.nodeName;
</script>

Contenuto dei nodi

Esistono quattro proprietà per leggere e scrivere ciò che si trova "all'interno" di un nodo. Scegliere quella giusta è importante per la correttezza, le prestazioni e la sicurezza.

textContent — testo semplice, sicuro

textContent ottiene o imposta il testo di un nodo e di tutti i suoi discendenti, ignorando qualsiasi markup. Quando lo leggi, ottieni il testo concatenato con i tag rimossi. Quando lo scrivi, la string viene inserita come testo letterale — qualsiasi < o > viene escapato, quindi è la scelta sicura per visualizzare dati non attendibili:

const div = document.createElement('div');
div.innerHTML = '<b>Hi</b> there';

console.log(div.textContent);          // "Hi there"  (tags stripped)

div.textContent = '<script>alert(1)<\/script>';
console.log(div.textContent);          // "<script>alert(1)</script>"  (inert text, not executed)

<!-- snippet: html-result -->

<div id="example"></div>
<script>
  const element = document.getElementById('example');
  element.textContent = 'Updated text content';
</script>

innerHTML — markup all'interno dell'elemento

innerHTML ottiene o imposta l'HTML tra il tag di apertura e di chiusura di un elemento. Impostandolo si analizza la string come HTML e si ricostruiscono i figli:

const div = document.createElement('div');
div.innerHTML = '<p>Para <span>one</span></p>';

console.log(div.innerHTML);            // "<p>Para <span>one</span></p>"
console.log(div.children.length);      // 1  (the <p>)

Avviso di sicurezza: non assegnare mai input non attendibile a innerHTML. Poiché il browser lo analizza come HTML, una string come <img src=x onerror=alert(1)> diventa un elemento reale ed eseguibile — un classico attacco cross-site-scripting (XSS). Usa textContent per i dati forniti dall'utente, oppure sanifica prima di inserire.

outerHTML — l'elemento incluso il suo tag

outerHTML è come innerHTML ma include i tag di apertura e chiusura dell'elemento stesso. Scrivervi sopra sostituisce l'elemento nel DOM, con una conseguenza inaspettata — la tua variabile punta ancora al vecchio nodo, ora staccato:

const div = document.createElement('div');
div.id = 'box';
div.innerHTML = 'content';

console.log(div.outerHTML);            // '<div id="box">content</div>'

// Setting outerHTML replaces the node; `div` is now stale.

nodeValue / data — testo all'interno di nodi di testo e commenti

Per i nodi di testo e commento (che non hanno innerHTML), usa nodeValue o il suo equivalente data per leggere e scrivere il loro contenuto:

const text = document.createTextNode('original');
console.log(text.nodeValue);           // "original"
console.log(text.data);                // "original"

text.data = 'changed';
console.log(text.nodeValue);           // "changed"

// On an element node, nodeValue is null.
const div = document.createElement('div');
console.log(div.nodeValue);            // null

Quale usare?

ProprietàFunziona suLeggeLa scrittura analizza HTML?Sicura per input non attendibili
textContentqualsiasi nodotesto semplice dei discendentino
innerHTMLelementimarkup internono (rischio XSS)
outerHTMLelementielemento + il suo tagsì (sostituisce il nodo)no (rischio XSS)
nodeValue / datatesto, commentoil testo del nodono

Per ulteriori informazioni sull'inserimento e la sostituzione di contenuto, consulta Modificare il documento.

Conclusione

Leggere le proprietà dei nodi è il fondamento di uno scripting DOM affidabile. Usa nodeType (con le costanti Node.*) per distinguere le categorie di nodi, tagName/nodeName per identificare i tag, e scegli deliberatamente una proprietà di contenuto: textContent per testo semplice sicuro, innerHTML/outerHTML quando vuoi intenzionalmente analizzare markup, e nodeValue/data per nodi di testo e commento puri. Usa textContent come impostazione predefinita per qualsiasi dato inserito dall'utente.

Esercitazione

Pratica
Cosa indica la proprietà 'nodeType' in un nodo DOM in JavaScript?
Cosa indica la proprietà 'nodeType' in un nodo DOM in JavaScript?
Was this page helpful?