Signatur
Beschreibung
Ein MutationObserver sammelt DOM-Änderungen in einer internen Warteschlange und liefert sie gebündelt und asynchron (als Microtask) an seine Callback-Funktion aus. takeRecords() holt diese noch nicht verarbeiteten Einträge sofort und synchron ab. Danach ist die Warteschlange leer, die Callback-Funktion bekommt diese Einträge also nicht mehr.
Der typische Einsatz ist direkt vor disconnect(): Wenn man den Observer beendet, gehen noch ausstehende Änderungen sonst verloren. Mit takeRecords() kann man sie vorher abholen und selbst verarbeiten, zum Beispiel beim Aufräumen einer Komponente oder vor dem Speichern eines Editor-Zustands.
Außerdem hilft die Methode, wenn man die Änderungen synchron braucht, etwa weil direkt nach einer DOM-Manipulation Code läuft, der auf einem aktuellen Zustand aufbauen muss, ohne auf den nächsten Microtask zu warten.
Rückgabewert
MutationRecord-Objekten, eines für jede erkannte und noch nicht ausgelieferte Änderung. Gibt es nichts abzuholen, ist das Array leer ([]).Beispiele
Ausstehende Änderungen vor disconnect() verarbeiten
const target = document.createElement('div');
document.body.append(target);
const handle = (records) => {
for (const r of records) {
console.log(`${r.type}: ${r.addedNodes.length} Knoten hinzugefügt`);
}
};
const observer = new MutationObserver(handle);
observer.observe(target, { childList: true });
// Synchrone Änderung – der Callback ist noch nicht gelaufen
target.append(document.createElement('span'));
// Vor dem Beenden die Warteschlange leeren und selbst verarbeiten
const pending = observer.takeRecords();
observer.disconnect();
handle(pending);
Warteschlange wird geleert – Callback bekommt nichts mehr
const el = document.createElement('p');
document.body.append(el);
const observer = new MutationObserver((records) => {
console.log('Callback:', records.length);
});
observer.observe(el, { attributes: true });
el.setAttribute('data-state', 'a');
el.setAttribute('data-state', 'b');
const records = observer.takeRecords();
console.log('Abgeholt:', records.length);
console.log('Erneut:', observer.takeRecords().length);
// Der Callback wird für diese beiden Änderungen nicht mehr aufgerufen
Synchroner Zugriff auf alte Attributwerte
const input = document.createElement('input');
document.body.append(input);
const observer = new MutationObserver(() => {});
observer.observe(input, {
attributes: true,
attributeOldValue: true,
attributeFilter: ['class']
});
input.className = 'valid';
input.className = 'invalid';
const history = observer.takeRecords().map((r) => ({
alt: r.oldValue,
neu: r.target.getAttribute(r.attributeName)
}));
console.log(history);
// Wichtig · Fallstricke
- Einträge sind danach weg: Was
takeRecords()zurückgibt, bekommt der Callback nicht mehr. Wer beide Wege nutzt, sollte dieselbe Verarbeitungsfunktion verwenden, damit keine Änderungen verloren gehen. disconnect()verwirft die Warteschlange: Ohne vorherigestakeRecords()sind ausstehende Einträge nachdisconnect()verloren.takeRecords()löst den Callback nicht aus. Es liefert nur Einträge, die schon erkannt wurden; spätere Änderungen landen wieder in der Warteschlange.MutationRecord.target.getAttribute()zeigt immer den aktuellen Wert, nicht den zum Zeitpunkt der Änderung. Für frühere Werte braucht manattributeOldValuebzw.characterDataOldValue.- Die Methode wird von allen modernen Browsern unterstützt (auch schon vom IE 11), in Node.js dagegen nur über DOM-Implementierungen wie jsdom.