Signatur
Beschreibung
Die Eigenschaft invalidIteratorState des XPathResult-Interfaces zeigt an, ob der Iterator eines Ergebnisses noch benutzt werden kann. Wichtig ist sie nur bei den Ergebnistypen UNORDERED_NODE_ITERATOR_TYPE und ORDERED_NODE_ITERATOR_TYPE. Diese Ergebnisse sind „live“: Sie verweisen direkt auf den DOM-Baum und liefern die Knoten erst nach und nach über iterateNext().
Ändert sich das Dokument nach dem Aufruf von document.evaluate(), etwa durch Einfügen, Entfernen oder Ändern von Knoten, wird der Iterator ungültig. Dann gibt invalidIteratorState den Wert true zurück, und jeder weitere Aufruf von iterateNext() löst eine DOMException mit dem Namen InvalidStateError aus.
Bei allen anderen Ergebnistypen ist der Wert immer false. Dazu gehören Snapshots (*_SNAPSHOT_TYPE), einzelne Knoten (*_NODE_TYPE) und primitive Werte (NUMBER_TYPE, STRING_TYPE, BOOLEAN_TYPE). Mit der Eigenschaft kannst du also vor dem Weiterlaufen prüfen, ob das Ergebnis noch zuverlässig ist, oder die Abfrage bei Bedarf neu ausführen.
Rückgabewert
true, wenn das Dokument seit der Auswertung verändert wurde und der Iterator ungültig ist, sonst false.Beispiele
Iterator vor und nach einer DOM-Änderung prüfen
document.body.innerHTML = '<p>Eins</p><p>Zwei</p>';
const result = document.evaluate(
'//p',
document,
null,
XPathResult.ORDERED_NODE_ITERATOR_TYPE,
null
);
console.log(result.invalidIteratorState);
// DOM verändern – der Iterator wird dadurch ungültig
document.body.append(document.createElement('div'));
console.log(result.invalidIteratorState);
Sicher iterieren und InvalidStateError abfangen
const collectTexts = (xpath) => {
const result = document.evaluate(
xpath, document, null,
XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null
);
const texts = [];
try {
let node;
while (!result.invalidIteratorState && (node = result.iterateNext())) {
texts.push(node.textContent);
}
} catch (err) {
if (err.name === 'InvalidStateError') {
console.warn('Dokument wurde während der Iteration verändert.');
} else {
throw err;
}
}
return texts;
};
document.body.innerHTML = '<li>A</li><li>B</li>';
console.log(collectTexts('//li'));
Knoten ändern – besser mit Snapshot
document.body.innerHTML = '<span>x</span><span>y</span>';
// Ein Snapshot wird durch DOM-Änderungen nicht ungültig
const snap = document.evaluate(
'//span', document, null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null
);
for (let i = 0; i < snap.snapshotLength; i++) {
snap.snapshotItem(i).textContent = `Eintrag ${i + 1}`;
}
console.log(snap.invalidIteratorState);
console.log(document.body.textContent);
// Wichtig · Fallstricke
- Häufiger Fehler: Wenn du in einer
iterateNext()-Schleife Knoten veränderst, zum Beispiel übertextContent,remove()odersetAttribute(), wird der Iterator sofort ungültig. Der nächste Aufruf wirft dann einenInvalidStateError. Sammle die Knoten deshalb zuerst oder nutze gleichORDERED_NODE_SNAPSHOT_TYPE. - Die Eigenschaft ist schreibgeschützt. Eine Zuweisung wird im nicht-strikten Modus ignoriert und löst im strikten Modus einen
TypeErroraus. - Bei allen Ergebnistypen außer den Iterator-Typen ist der Wert immer
false. Er sagt dort also nichts darüber aus, ob das Ergebnis noch aktuell ist: Ein Snapshot kann zum Beispiel Knoten enthalten, die inzwischen entfernt wurden. - Kompatibilität: Die Eigenschaft wird von allen modernen Browsern unterstützt (Chrome, Firefox, Safari, Edge). In Node.js gibt es sie nicht von Haus aus, sondern nur über DOM-Implementierungen wie
jsdom.