Start · Sprachen · JavaScript · Referenz · NodeIterator.referenceNode

NodeIterator.referenceNode

Eigenschaft

Gibt den schreibgeschützten Ankerknoten eines <code>NodeIterator</code> zurück. Die Position des Iterators bleibt an ihm verankert, auch wenn sich das DOM verändert.

seit JavaScript DOM Level 2 Traversal – Baseline: alle modernen Br Kategorie: webapi

Signatur

NodeIterator.referenceNode

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

Typ
Node
Beschreibung
Der Knoten, an dem der Iterator gerade verankert ist. Die Eigenschaft ist nie 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);
true true a false a true

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);
Vorher: b Nachher: a Weiter mit: c

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 referenceNode wird still ignoriert und wirft im Strict Mode einen TypeError. Die Position ändern Sie nur mit nextNode() und previousNode().
  • Filter wird nicht angewendet: Der Referenzknoten muss nicht zu whatToShow oder 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 pointerBeforeReferenceNode aus. 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 ist referenceNode danach unverändert die Wurzel.
  • TreeWalker hat keine vergleichbare Eigenschaft, sondern das beschreibbare currentNode.
  • Kompatibilität: wird in allen modernen Browsern unterstützt. Im Internet Explorer fehlte referenceNode.