Start · Sprachen · JavaScript · Referenz · NodeIterator.pointerBeforeReferenceNode

NodeIterator.pointerBeforeReferenceNode

Eigenschaft

Schreibgeschütztes boolesches Flag, das angibt, ob der interne Zeiger eines <code>NodeIterator</code> vor (<code>true</code>) oder nach (<code>false</code>) seinem <code>referenceNode</code> steht.

seit JavaScript Baseline: alle Browser (DOM Level 2 Traversal, sei Kategorie: webapi

Signatur

get NodeIterator.prototype.pointerBeforeReferenceNode

Beschreibung

Ein NodeIterator merkt sich seine Position nicht als Index, sondern als Paar aus einem Referenzknoten (referenceNode) und einem Flag pointerBeforeReferenceNode. Das Flag sagt aus, ob der gedachte Zeiger direkt vor oder direkt nach dem Referenzknoten liegt. So lässt sich eindeutig festlegen, welcher Knoten beim nächsten Aufruf von nextNode() oder previousNode() geliefert wird.

Der Ablauf im Einzelnen:

  • Direkt nach document.createNodeIterator() ist referenceNode der Wurzelknoten und das Flag ist true. Der erste nextNode()-Aufruf liefert deshalb (sofern der Filter ihn akzeptiert) die Wurzel selbst.
  • Nach nextNode() steht der Zeiger hinter dem gelieferten Knoten, das Flag ist also false.
  • Nach previousNode() steht der Zeiger vor dem gelieferten Knoten, das Flag ist also true.

Im Alltag braucht man die Eigenschaft selten direkt. Sie hilft aber beim Debuggen von Traversierungslogik, beim Speichern und Wiederherstellen einer Iterationsposition und vor allem dann, wenn man verstehen will, wie sich ein Iterator verhält, sobald Knoten während der Iteration aus dem DOM entfernt werden. Der Browser verschiebt Referenzknoten und Flag in diesem Fall automatisch.

Rückgabewert

Typ
boolean
Beschreibung
true, wenn der Zeiger vor dem referenceNode steht; false, wenn er dahinter steht. Die Eigenschaft ist schreibgeschützt.

Beispiele

Wie sich das Flag bei nextNode() und previousNode() ändert

const list = document.createElement('ul');
list.innerHTML = '<li>A</li><li>B</li>';

const it = document.createNodeIterator(list, NodeFilter.SHOW_ELEMENT);

// Ausgangszustand: Zeiger steht vor der Wurzel
console.log(it.referenceNode.nodeName, it.pointerBeforeReferenceNode);

it.nextNode(); // liefert UL (Wurzel)
console.log(it.referenceNode.nodeName, it.pointerBeforeReferenceNode);

it.nextNode(); // liefert LI "A"
console.log(it.referenceNode.textContent, it.pointerBeforeReferenceNode);

it.previousNode(); // liefert erneut LI "A", Zeiger springt davor
console.log(it.referenceNode.textContent, it.pointerBeforeReferenceNode);
UL true UL false A false A true

Referenzknoten wird während der Iteration entfernt

const list = document.createElement('ul');
list.innerHTML = '<li>A</li><li>B</li><li>C</li>';
document.body.append(list);

const it = document.createNodeIterator(list, NodeFilter.SHOW_ELEMENT);
it.nextNode();           // UL
it.nextNode();           // LI A
it.nextNode();           // LI B
const b = it.previousNode(); // LI B, Zeiger jetzt davor

console.log(b.textContent, it.pointerBeforeReferenceNode);

b.remove(); // Browser verschiebt den Referenzknoten auf den folgenden Knoten
console.log(it.referenceNode.textContent, it.pointerBeforeReferenceNode);

console.log(it.nextNode().textContent); // Iteration läuft nahtlos weiter
B true C true C

Debug-Hilfe: aktuelle Iterator-Position beschreiben

const describePosition = (iterator) => {
  const node = iterator.referenceNode;
  const label = node.nodeType === Node.ELEMENT_NODE
    ? `<${node.localName}>`
    : node.nodeName;
  return iterator.pointerBeforeReferenceNode
    ? `Zeiger vor ${label}`
    : `Zeiger nach ${label}`;
};

const section = document.createElement('section');
section.innerHTML = '<h2>Titel</h2><p>Text</p>';
const it = document.createNodeIterator(section, NodeFilter.SHOW_ELEMENT);

console.log(describePosition(it));
it.nextNode();
it.nextNode();
console.log(describePosition(it));
Zeiger vor <section> Zeiger nach <h2>

// Wichtig · Fallstricke

  • Schreibgeschützt: Eine Zuweisung wie it.pointerBeforeReferenceNode = false wird still ignoriert (im Strict Mode gibt es einen TypeError). Die Position lässt sich nur über nextNode() und previousNode() ändern.
  • Entfernte Knoten: Wird der Referenzknoten (oder einer seiner Vorfahren innerhalb der Wurzel) entfernt, passt der Browser referenceNode und das Flag an. Steht der Zeiger vor dem Knoten, rückt er auf den nächsten Knoten danach. Gibt es keinen, springt er auf den vorherigen Knoten und das Flag wird false. Steht der Zeiger nach dem Knoten, wandert er auf den vorhergehenden Knoten in Dokumentreihenfolge.
  • Filter werden dabei ignoriert: Beim Verschieben nach einem Entfernen berücksichtigt der Browser weder whatToShow noch den NodeFilter. referenceNode kann deshalb vorübergehend ein Knoten sein, den der Filter eigentlich ausschließt, zum Beispiel ein Textknoten.
  • TreeWalker hat kein solches Flag. Dort gibt es stattdessen die frei setzbare Eigenschaft currentNode.
  • Kompatibilität: Wird in allen modernen Browsern unterstützt. Ältere Browser (z. B. Firefox vor Version 3.5 und Internet Explorer) boten die Eigenschaft nicht oder nur eingeschränkt an. Node.js hat kein eingebautes DOM, dort ist sie nur über Bibliotheken wie jsdom verfügbar.