Start · Sprachen · JavaScript · Referenz · MutationObserver.takeRecords()

MutationObserver.takeRecords()

Methode

Gibt alle erkannten, aber noch nicht an den Callback ausgelieferten <code>MutationRecord</code>-Objekte als Array zurück und leert die Warteschlange des Observers.

seit JavaScript Baseline: alle Browser (DOM4) Kategorie: webapi

Signatur

MutationObserver.prototype.takeRecords()

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

Typ
MutationRecord[]
Beschreibung
Ein Array mit 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);
childList: 1 Knoten hinzugefügt

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
Abgeholt: 2 Erneut: 0

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);
[{ alt: null, neu: 'invalid' }, { alt: 'valid', neu: 'invalid' }]

// 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 vorheriges takeRecords() sind ausstehende Einträge nach disconnect() 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 man attributeOldValue bzw. 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.