Signatur
Beschreibung
Ein NodeIterator speichert seine Position nicht als Index, sondern als Referenzknoten und dazu ein Flag. referenceNode gibt diesen Ankerknoten zurück. Ob der gedachte Zeiger vor oder hinter dem Knoten steht, verrät die Schwester-Eigenschaft pointerBeforeReferenceNode. Erst beide Werte zusammen beschreiben die Position vollständig.
Direkt nach document.createNodeIterator() ist referenceNode der Wurzelknoten (root), und pointerBeforeReferenceNode ist true. Nach jedem erfolgreichen Aufruf von nextNode() oder previousNode() wird der zurückgegebene Knoten zum neuen Referenzknoten. Nach nextNode() steht der Zeiger hinter dem Knoten, nach previousNode() davor.
Nützlich ist die Eigenschaft vor allem, wenn das DOM während der Iteration verändert wird. Fügen Sie Knoten ein, bleibt der Iterator am Referenzknoten verankert. Entfernen Sie den Referenzknoten selbst oder einen seiner Vorfahren, verschiebt der Browser den Anker automatisch auf einen benachbarten Knoten, der noch im Baum ist. So lässt sich die Iteration fortsetzen, ohne den Iterator neu anzulegen. Mit referenceNode können Sie außerdem die aktuelle Position abfragen, ohne den Iterator zu bewegen, etwa für Debugging-Zwecke oder zum Hervorheben des aktuellen Elements.
Rückgabewert
null. Anfangs ist es der Wurzelknoten des Iterators.Beispiele
Anfangszustand und Bewegung des Ankers
const list = document.createElement('ul');
['a', 'b', 'c'].forEach((id) => {
const li = document.createElement('li');
li.id = id;
list.append(li);
});
const it = document.createNodeIterator(list, NodeFilter.SHOW_ELEMENT);
console.log(it.referenceNode === list, it.pointerBeforeReferenceNode);
it.nextNode(); // liefert zuerst die Wurzel selbst
it.nextNode(); // li#a
console.log(it.referenceNode.id, it.pointerBeforeReferenceNode);
it.previousNode(); // wieder li#a, Zeiger jetzt davor
console.log(it.referenceNode.id, it.pointerBeforeReferenceNode);
Anker passt sich beim Entfernen von Knoten an
const list = document.createElement('ul');
['a', 'b', 'c'].forEach((id) => {
const li = document.createElement('li');
li.id = id;
list.append(li);
});
const it = document.createNodeIterator(list, NodeFilter.SHOW_ELEMENT);
it.nextNode(); // ul
it.nextNode(); // li#a
const b = it.nextNode(); // li#b
console.log('Vorher:', it.referenceNode.id);
b.remove(); // Referenzknoten wird entfernt
console.log('Nachher:', it.referenceNode.id);
// Die Iteration läuft trotzdem korrekt weiter
console.log('Weiter mit:', it.nextNode().id);
Aktuelle Position hervorheben, ohne den Iterator zu bewegen
const it = document.createNodeIterator(
document.body,
NodeFilter.SHOW_ELEMENT,
(node) => node.matches('p')
? NodeFilter.FILTER_ACCEPT
: NodeFilter.FILTER_SKIP
);
const highlightCurrent = () => {
document.querySelectorAll('.current').forEach((el) => el.classList.remove('current'));
const node = it.referenceNode;
if (node instanceof Element && node !== document.body) {
node.classList.add('current');
}
};
document.querySelector('#next')?.addEventListener('click', () => {
if (it.nextNode()) highlightCurrent();
});
// Wichtig · Fallstricke
- Schreibgeschützt: Eine Zuweisung an
referenceNodewird still ignoriert und wirft im Strict Mode einenTypeError. Die Position ändern Sie nur mitnextNode()undpreviousNode(). - Filter wird nicht angewendet: Der Referenzknoten muss nicht zu
whatToShowoder zum Filter passen. Am Anfang ist er immer die Wurzel, und nach dem Entfernen eines Knotens kann er auch ein Textknoten oder ein anderer, eigentlich gefilterter Knoten sein. Prüfen Sie den Knotentyp, bevor Sie Element-Methoden aufrufen. - Nur zusammen aussagekräftig: Werten Sie immer auch
pointerBeforeReferenceNodeaus. Derselbe Referenzknoten kann für zwei verschiedene Positionen stehen, je nachdem, ob der Zeiger davor oder dahinter steht. - Der erste Aufruf von
nextNode()liefert die Wurzel selbst, sofern sie den Filter besteht. Deshalb istreferenceNodedanach unverändert die Wurzel. TreeWalkerhat keine vergleichbare Eigenschaft, sondern das beschreibbarecurrentNode.- Kompatibilität: wird in allen modernen Browsern unterstützt. Im Internet Explorer fehlte
referenceNode.