Signatur
Beschreibung
NodeIterator durchläuft alle Knoten unterhalb eines Wurzelknotens (root) als flache Liste in Dokumentreihenfolge (Tiefensuche, Pre-Order). Eine Instanz legt man nicht mit einem Konstruktor an, sondern über document.createNodeIterator(root, whatToShow, filter). Mit nextNode() geht man vorwärts, mit previousNode() rückwärts. Ist das Ende erreicht, liefern beide null.
Anders als querySelectorAll() findet ein NodeIterator nicht nur Elemente. Er erfasst auch Textknoten, Kommentare und Verarbeitungsanweisungen. Die Bitmaske whatToShow (z. B. NodeFilter.SHOW_TEXT oder NodeFilter.SHOW_COMMENT) legt fest, welche Knotentypen berücksichtigt werden. Eine optionale Filterfunktion kann jeden Knoten zusätzlich mit NodeFilter.FILTER_ACCEPT annehmen oder mit FILTER_REJECT bzw. FILTER_SKIP überspringen.
Wichtige Eigenschaften (nur lesbar):
root: der Wurzelknoten der IterationwhatToShow: die verwendete Bitmaskefilter: der übergebene Filter odernullreferenceNode: der Knoten, an dem der Iterator gerade stehtpointerBeforeReferenceNode:true, wenn der Zeiger vor dem Referenzknoten steht
Die Methode detach() hat heute keine Wirkung mehr. Einsatzgebiete sind z. B. alle Textknoten für Suchen und Hervorheben einsammeln, Kommentare auswerten oder große DOM-Bereiche ohne Rekursion durchlaufen. Wenn du die Baumstruktur brauchst (Eltern, Geschwister, Kinder), nimm stattdessen TreeWalker.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $root Pflicht | Node | Parameter von document.createNodeIterator(): der Wurzelknoten, ab dem iteriert wird. Er selbst ist der erste Kandidat. |
|
| $whatToShow | number | NodeFilter.SHOW_ALL (0xFFFFFFFF) | Bitmaske aus NodeFilter.SHOW_*-Konstanten, mehrere verknüpft mit |, z. B. NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT. |
| $filter | NodeFilter | ((node: Node) => number) | null | null | Funktion oder Objekt mit einer Methode acceptNode(node). Rückgabe: NodeFilter.FILTER_ACCEPT, FILTER_REJECT oder FILTER_SKIP. Bei NodeIterator wirken REJECT und SKIP gleich. |
Rückgabewert
document.createNodeIterator() gibt eine neue NodeIterator-Instanz zurück. nextNode() und previousNode() geben jeweils einen Node zurück oder null, wenn keine weiteren Knoten vorhanden sind.Beispiele
Alle Textknoten eines Bereichs sammeln
document.body.innerHTML = '<article id="post"><h2>Titel</h2><p>Hallo <b>Welt</b></p></article>';
const root = document.getElementById('post');
const iterator = document.createNodeIterator(root, NodeFilter.SHOW_TEXT);
const texte = [];
let node;
while ((node = iterator.nextNode())) {
texte.push(node.nodeValue);
}
console.log(texte);
Mit Filterfunktion: leere Textknoten überspringen
const iterator = document.createNodeIterator(
document.body,
NodeFilter.SHOW_TEXT,
(node) => node.nodeValue.trim()
? NodeFilter.FILTER_ACCEPT
: NodeFilter.FILTER_REJECT
);
let anzahlWoerter = 0;
for (let n = iterator.nextNode(); n; n = iterator.nextNode()) {
anzahlWoerter += n.nodeValue.trim().split(/\s+/).length;
}
console.log(`Wörter auf der Seite: ${anzahlWoerter}`);
Kommentare finden und entfernen
document.body.innerHTML = '<div><!-- TODO --><p>Inhalt</p><!-- debug --></div>';
const iterator = document.createNodeIterator(document.body, NodeFilter.SHOW_COMMENT);
const kommentare = [];
let c;
while ((c = iterator.nextNode())) kommentare.push(c);
// Erst sammeln, dann entfernen
kommentare.forEach((k) => k.remove());
console.log(kommentare.map((k) => k.data.trim()), document.body.innerHTML);
Vorwärts und rückwärts navigieren
document.body.innerHTML = '<ul><li>A</li><li>B</li><li>C</li></ul>';
const it = document.createNodeIterator(
document.querySelector('ul'),
NodeFilter.SHOW_ELEMENT,
(n) => n.tagName === 'LI' ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP
);
console.log(it.nextNode().textContent); // A
console.log(it.nextNode().textContent); // B
console.log(it.previousNode().textContent); // B (Zeiger kehrt um)
console.log(it.pointerBeforeReferenceNode);
// Wichtig · Fallstricke
- Richtungswechsel: Der Iterator steht immer zwischen zwei Knoten. Rufst du nach
nextNode()direktpreviousNode()auf, bekommst du denselben Knoten noch einmal. FILTER_REJECTundFILTER_SKIP: BeiNodeIteratorüberspringen beide nur den einzelnen Knoten, seine Nachfahren werden trotzdem besucht. Nur beiTreeWalkerschließtFILTER_REJECTden ganzen Teilbaum aus.- DOM-Änderungen: Der Iterator bleibt gültig, wenn sich das DOM ändert. Wird der Referenzknoten entfernt, rückt er automatisch weiter. Trotzdem ist es übersichtlicher, Knoten erst zu sammeln und danach zu verändern.
- Kein JS-Iterator:
NodeIteratorsetztSymbol.iteratornicht um.for...ofund der Spread-Operator funktionieren daher nicht direkt, du brauchst einewhile-Schleife oder eine eigene Generatorfunktion. - Die Filterfunktion darf das DOM nicht verändern. Wirft sie eine Ausnahme, bricht die Iteration ab.
detach()ist veraltet und hat keine Wirkung. Die früheren ParameterSHOW_ENTITY,SHOW_NOTATIONusw. sind ebenfalls veraltet.- Kompatibilität: Wird von allen modernen Browsern (und seit IE9) unterstützt. Für reine Elementsuchen ist
querySelectorAll()meist einfacher und schneller.