Start · Sprachen · JavaScript · Referenz · MutationRecord.oldValue

MutationRecord.oldValue

Eigenschaft

Schreibgeschützte Eigenschaft, die den Attributwert oder die Zeichendaten eines Knotens <em>vor</em> der beobachteten Änderung enthält – oder <code>null</code>.

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

Signatur

MutationRecord.oldValue

Beschreibung

oldValue ist eine schreibgeschützte Eigenschaft eines MutationRecord, den ein MutationObserver an seine Callback-Funktion übergibt. Sie enthält den Zustand vor der Änderung. So lässt sich ein Vorher-Nachher-Vergleich machen, ohne dass man den alten Zustand selbst zwischenspeichern muss.

Welchen Inhalt die Eigenschaft hat, hängt vom type des Datensatzes ab:

  • "attributes": der vorherige Wert des geänderten Attributs (attributeName). War das Attribut vorher nicht vorhanden, steht hier null.
  • "characterData": der vorherige Text des Text-, Comment- oder CDATASection-Knotens.
  • "childList": immer null.

Ganz wichtig: Der Wert wird nur dann erfasst, wenn man ihn ausdrücklich anfordert. Dazu setzt man beim Aufruf von observe() die Option attributeOldValue: true bzw. characterDataOldValue: true. Ohne diese Optionen ist oldValue immer null. Den aktuellen Wert liest man dagegen direkt vom Zielknoten (record.target) aus, zum Beispiel über getAttribute() oder data.

Rückgabewert

Typ
string | null
Beschreibung
Der vorherige Attributwert oder die vorherigen Zeichendaten als Zeichenkette. null gibt es bei childList-Datensätzen, wenn die passende *OldValue-Option fehlt oder wenn ein Attribut vorher nicht vorhanden war.

Beispiele

Attributänderung mit Vorher-/Nachher-Wert protokollieren

const box = document.createElement('div');
box.className = 'klein';
document.body.append(box);

const observer = new MutationObserver((records) => {
  for (const record of records) {
    if (record.type === 'attributes') {
      const neu = record.target.getAttribute(record.attributeName);
      console.log(`${record.attributeName}: "${record.oldValue}" → "${neu}"`);
    }
  }
});

// attributeOldValue ist nötig, sonst ist oldValue null
observer.observe(box, { attributes: true, attributeOldValue: true });

box.className = 'gross';
class: "klein" → "gross"

Textänderungen in einem editierbaren Bereich verfolgen

const editor = document.createElement('p');
editor.textContent = 'Hallo';
document.body.append(editor);
const textNode = editor.firstChild;

const observer = new MutationObserver((records) => {
  records.forEach(({ type, oldValue, target }) => {
    if (type === 'characterData') {
      console.log('Vorher:', oldValue, '| Nachher:', target.data);
    }
  });
});

observer.observe(editor, {
  characterData: true,
  characterDataOldValue: true,
  subtree: true // Textknoten sind Kinder von <p>
});

textNode.data = 'Hallo Welt';
Vorher: Hallo | Nachher: Hallo Welt

Neu hinzugefügte Attribute erkennen (oldValue === null)

const button = document.createElement('button');
document.body.append(button);

const observer = new MutationObserver((records) => {
  for (const r of records) {
    if (r.oldValue === null) {
      console.log(`Attribut "${r.attributeName}" wurde neu gesetzt`);
    } else if (!r.target.hasAttribute(r.attributeName)) {
      console.log(`Attribut "${r.attributeName}" entfernt (war "${r.oldValue}")`);
    }
  }
});

observer.observe(button, {
  attributeFilter: ['disabled', 'aria-busy'],
  attributeOldValue: true
});

button.setAttribute('disabled', '');
button.setAttribute('aria-busy', 'true');
button.removeAttribute('aria-busy');
Attribut "disabled" wurde neu gesetzt Attribut "aria-busy" wurde neu gesetzt Attribut "aria-busy" entfernt (war "true")

// Wichtig · Fallstricke

  • Häufigster Fehler: oldValue ist immer null, wenn man attributeOldValue: true bzw. characterDataOldValue: true nicht setzt. Setzt man eine dieser Optionen, gelten attributes bzw. characterData automatisch als true.
  • null kann zweierlei heißen: Das Attribut war vorher nicht vorhanden, oder oldValue wurde nicht angefordert. Ein vorher leeres Attribut (z. B. disabled="") liefert dagegen "".
  • Die Callback-Funktion wird gesammelt als Mikrotask aufgerufen. Bei mehreren Änderungen hintereinander bekommt jede Änderung einen eigenen Datensatz mit ihrem jeweiligen Vorher-Wert. record.target zeigt aber schon den endgültigen Zustand. Den genauen Zwischenwert erhält man nur aus dem oldValue des jeweils nächsten Datensatzes.
  • Auch das Setzen desselben Werts (z. B. el.className = el.className) erzeugt einen Datensatz, bei dem oldValue gleich dem neuen Wert ist.
  • Wird in einem MutationObserver ein Attribut des beobachteten Elements geändert, kann eine Endlosschleife entstehen. Deshalb vorher den Wert vergleichen oder den Observer mit disconnect() vorübergehend trennen.
  • Die Eigenschaft wird von allen modernen Browsern unterstützt. In Node.js gibt es sie nur über DOM-Implementierungen wie jsdom.