Signatur
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
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
}
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);
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);
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
// Wichtig · Fallstricke
- Leerraum-Textknoten: Zeilenumbrüche und Einrückungen im HTML erzeugen Textknoten.
firstChild/nextSiblingliefern daher oft kein Element – für reine ElementnavigationfirstElementChild,nextElementSiblingoderchildrenverwenden. - Live-Listen:
childNodesist eine liveNodeList. Wer in einer Schleife Kinder entfernt, überspringt Knoten – vorher mit[...node.childNodes]oderArray.from()kopieren. - Verschieben statt Kopieren:
appendChild()/insertBefore()mit einem bereits eingehängten Knoten verschiebt ihn. Für eine KopiecloneNode(true)nutzen – dabei werden peraddEventListenerregistrierte Listener nicht mitkopiert, und doppelteid-Attribute sind möglich. - Sicherheit:
textContentist beim Einfügen von Benutzereingaben sicher (kein HTML-Parsing),innerHTMLdagegen XSS-anfällig. Für dynamische Inhalte bevorzugtcreateTextNode()odertextContentverwenden. - Performance: Viele einzelne Einfügeoperationen lösen wiederholte Layout-Berechnungen aus; besser zuerst in einem
DocumentFragmentsammeln und einmal einhängen. - Kompatibilität: Kernfunktionen sind in allen Browsern verfügbar. Neuere Eigenschaften wie
isConnectedundgetRootNode()fehlen nur im Internet Explorer. Die modernen Methodenappend(),prepend(),before(),after(),remove(),replaceWith()gehören formal zuParentNode/ChildNode, nicht zuNode. In Node.js existiertNodenur mit DOM-Implementierungen wie jsdom.