Signatur
Beschreibung
Die schreibgeschützte Eigenschaft nextSibling eines MutationRecord gibt an, welcher Knoten direkt hinter den in addedNodes bzw. removedNodes aufgeführten Knoten steht. Zusammen mit previousSibling lässt sich damit genau bestimmen, an welcher Stelle im Elternknoten (target) die Änderung stattgefunden hat.
Einen Wert hat die Eigenschaft nur bei Datensätzen vom Typ "childList". Bei "attributes"- und "characterData"-Mutationen ist sie immer null. Auch bei childList-Mutationen ist sie null, wenn die Knoten am Ende der Kindliste eingefügt bzw. von dort entfernt wurden (z. B. mit appendChild()).
Nützlich ist das vor allem für Undo-/Redo-Funktionen, für die Synchronisierung eines DOM-Abbilds (virtuelles DOM, kollaboratives Bearbeiten) oder für Protokolle, in denen Einfügungen genau wiederhergestellt werden sollen: Mit target.insertBefore(knoten, record.nextSibling) lässt sich ein entfernter Knoten wieder an seine alte Position setzen.
Rückgabewert
null, wenn es keinen gibt oder der Datensatz nicht vom Typ childList ist.Beispiele
Einfügeposition protokollieren
const list = document.createElement('ul');
list.innerHTML = '<li id="a">A</li><li id="c">C</li>';
document.body.append(list);
const observer = new MutationObserver((records) => {
for (const record of records) {
if (record.type !== 'childList') continue;
const next = record.nextSibling;
console.log('Eingefügt vor:', next ? next.id : '(Listenende)');
}
});
observer.observe(list, { childList: true });
const b = document.createElement('li');
b.id = 'b';
list.insertBefore(b, document.getElementById('c'));
const d = document.createElement('li');
d.id = 'd';
list.append(d);
Entfernte Knoten wiederherstellen (Undo)
const container = document.createElement('div');
container.innerHTML = '<p>1</p><p>2</p><p>3</p>';
document.body.append(container);
const undoStack = [];
const observer = new MutationObserver((records) => {
for (const r of records) {
if (r.removedNodes.length) {
undoStack.push({ target: r.target, nodes: [...r.removedNodes], next: r.nextSibling });
}
}
});
observer.observe(container, { childList: true });
container.children[1].remove(); // <p>2</p> entfernen
// Datensätze sofort abholen statt auf den Callback zu warten
for (const r of observer.takeRecords()) {
undoStack.push({ target: r.target, nodes: [...r.removedNodes], next: r.nextSibling });
}
const undo = () => {
const entry = undoStack.pop();
if (!entry) return;
observer.disconnect(); // eigene Änderung nicht erneut protokollieren
for (const node of entry.nodes) {
entry.target.insertBefore(node, entry.next);
}
observer.observe(container, { childList: true });
};
undo();
console.log(container.textContent);
Bei Attribut-Mutationen immer null
const el = document.createElement('div');
document.body.append(el);
const observer = new MutationObserver(([record]) => {
console.log(record.type, record.nextSibling);
observer.disconnect();
});
observer.observe(el, { attributes: true });
el.setAttribute('data-state', 'aktiv');
// Wichtig · Fallstricke
- Text- und Kommentarknoten:
nextSiblingbezieht sich auf Knoten, nicht auf Elemente. Leerraum zwischen Tags ist ein Textknoten, daher ist der Wert oft ein#text-Knoten statt des erwarteten Elements. Wer ein Element braucht, prüftnodeTypeoder läuft mitnextElementSiblingweiter. - Momentaufnahme: Der Wert gibt den Zustand zum Zeitpunkt der Mutation wieder. Weil Callbacks asynchron (als Microtask) laufen, kann der Knoten inzwischen verschoben oder entfernt worden sein. Vor
insertBefore()sollte man prüfen, obnext.parentNode === targetgilt, sonst gibt es eineNotFoundError-DOMException. - Nur bei
childList: Die Eigenschaft wird nur befüllt, wenn der Observer mit{ childList: true }(optionalsubtree: true) registriert wurde. - Kompatibilität: Wird von allen modernen Browsern unterstützt (Chrome, Firefox, Safari, Edge). Der Internet Explorer kennt
MutationObservererst ab Version 11.