Start · Sprachen · JavaScript · Referenz · Node

Node

Schnittstelle

Abstrakte Basisschnittstelle des DOM, von der <code>Document</code>, <code>Element</code>, <code>Text</code>, <code>Comment</code> u. a. Baumstruktur, Navigation und Manipulation erben.

seit JavaScript Baseline: alle Browser (DOM Level 1+) Kategorie: webapi

Signatur

interface Node extends EventTarget

Beschreibung

Node ist die abstrakte Basisschnittstelle für alle Objekte im DOM-Baum. Document, DocumentFragment, Element, Attr, CharacterData (und damit Text, Comment, CDATASection, ProcessingInstruction) sowie DocumentType erben von Node. Da Node selbst von EventTarget erbt, kann jeder Knoten Ereignisse empfangen.

Die Schnittstelle stellt vor allem drei Dinge bereit:

  • Identifikation: nodeType, nodeName, nodeValue, textContent, baseURI, isConnected.
  • Navigation im Baum: parentNode, parentElement, childNodes, firstChild, lastChild, previousSibling, nextSibling, ownerDocument, getRootNode().
  • Manipulation und Vergleich: appendChild(), insertBefore(), removeChild(), replaceChild(), cloneNode(), contains(), compareDocumentPosition(), isEqualNode(), isSameNode(), normalize(), hasChildNodes().

Man kann Node nicht direkt instanziieren (new Node() wirft einen TypeError); Knoten entstehen über Fabrikmethoden wie document.createElement() oder document.createTextNode(). Node ist aber als globales Objekt verfügbar – nützlich für instanceof-Prüfungen und die Konstanten Node.ELEMENT_NODE (1), Node.TEXT_NODE (3), Node.COMMENT_NODE (8), Node.DOCUMENT_NODE (9), Node.DOCUMENT_FRAGMENT_NODE (11) usw.

Wichtig ist der Unterschied zwischen Knoten und Elementen: childNodes, firstChild oder nextSibling liefern auch Text- und Kommentarknoten (etwa Leerzeichen-Zeilenumbrüche aus dem HTML), während die Element-Varianten wie children oder nextElementSibling (aus Element/ParentNode) nur Elemente berücksichtigen.

Rückgabewert

Typ
Node
Beschreibung
Keine direkte Rückgabe – Node ist eine abstrakte Schnittstelle; konkrete Knoten sind Instanzen von Unterklassen wie Element oder Text.

Beispiele

Knoten erzeugen und in den Baum einhängen

// Node kann nicht direkt instanziiert werden – Fabrikmethoden nutzen
const liste = document.createElement('ul');
const eintrag = document.createElement('li');
const text = document.createTextNode('Erster Eintrag');

eintrag.appendChild(text);
liste.appendChild(eintrag);
document.body.appendChild(liste);

console.log(eintrag instanceof Node);   // true
console.log(text.nodeType === Node.TEXT_NODE); // true
console.log(liste.isConnected);         // true

try {
  new Node();
} catch (e) {
  console.log(e.constructor.name);      // TypeError
}
true true true TypeError

Nur Elementknoten aus childNodes filtern

const container = document.createElement('div');
container.innerHTML = `
  <p>Absatz</p>
  <!-- Kommentar -->
  <span>Span</span>
`;

console.log(container.childNodes.length); // inkl. Text- und Kommentarknoten

const elemente = [...container.childNodes]
  .filter((n) => n.nodeType === Node.ELEMENT_NODE)
  .map((n) => n.nodeName);

console.log(elemente);
5 ["P", "SPAN"]

Klick außerhalb eines Menüs erkennen mit contains()

const menue = document.createElement('nav');
menue.innerHTML = '<button>Öffnen</button>';
document.body.appendChild(menue);

const beiKlick = (event) => {
  // contains() prüft, ob der Zielknoten Nachfahre (oder der Knoten selbst) ist
  if (!menue.contains(event.target)) {
    console.log('Klick außerhalb – Menü schließen');
  }
};

document.addEventListener('click', beiKlick);
// Aufräumen, wenn nicht mehr benötigt:
// document.removeEventListener('click', beiKlick);
Klick außerhalb – Menü schließen (bei Klick außerhalb)

Knoten klonen, verschieben und vergleichen

const vorlage = document.createElement('div');
vorlage.className = 'karte';
vorlage.textContent = 'Hallo';

const kopie = vorlage.cloneNode(true); // tiefe Kopie
console.log(kopie.isEqualNode(vorlage)); // true – gleiche Struktur
console.log(kopie.isSameNode(vorlage));  // false – anderes Objekt

const ziel = document.body;
ziel.appendChild(vorlage);
ziel.insertBefore(kopie, vorlage); // kopie vor vorlage einfügen

const pos = vorlage.compareDocumentPosition(kopie);
console.log(Boolean(pos & Node.DOCUMENT_POSITION_PRECEDING)); // true

// Entfernen (modern: kopie.remove())
ziel.removeChild(kopie);
console.log(kopie.parentNode); // null
true false true null

// Wichtig · Fallstricke

  • Leerraum-Textknoten: Zeilenumbrüche und Einrückungen im HTML erzeugen Textknoten. firstChild/nextSibling liefern daher oft kein Element – für reine Elementnavigation firstElementChild, nextElementSibling oder children verwenden.
  • Live-Listen: childNodes ist eine live NodeList. Wer in einer Schleife Kinder entfernt, überspringt Knoten – vorher mit [...node.childNodes] oder Array.from() kopieren.
  • Verschieben statt Kopieren: appendChild()/insertBefore() mit einem bereits eingehängten Knoten verschiebt ihn. Für eine Kopie cloneNode(true) nutzen – dabei werden per addEventListener registrierte Listener nicht mitkopiert, und doppelte id-Attribute sind möglich.
  • Sicherheit: textContent ist beim Einfügen von Benutzereingaben sicher (kein HTML-Parsing), innerHTML dagegen XSS-anfällig. Für dynamische Inhalte bevorzugt createTextNode() oder textContent verwenden.
  • Performance: Viele einzelne Einfügeoperationen lösen wiederholte Layout-Berechnungen aus; besser zuerst in einem DocumentFragment sammeln und einmal einhängen.
  • Kompatibilität: Kernfunktionen sind in allen Browsern verfügbar. Neuere Eigenschaften wie isConnected und getRootNode() fehlen nur im Internet Explorer. Die modernen Methoden append(), prepend(), before(), after(), remove(), replaceWith() gehören formal zu ParentNode/ChildNode, nicht zu Node. In Node.js existiert Node nur mit DOM-Implementierungen wie jsdom.