Wenn DOM-Elemente mit herkömmlichen Methoden wie appendChild() oder insertBefore() neu zugeordnet werden, entfernt der Browser das Element implizit aus dem DOM und fügt es dann an der neuen Position ein. Durch diesen Vorgang des Entfernens und Einfügens werden viele interne Zustände zurückgesetzt. Das führt dazu, dass <iframe>-Elemente neu geladen, CSS-Animationen neu gestartet und Eingabefelder nicht mehr fokussiert werden.
Wenn Sie ein Element verschieben und seinen Status beibehalten möchten, verwenden Sie die moveBefore() API. Bei dieser Methode wird eine atomare Verschiebung durchgeführt, wobei die Schritte zum Entfernen und Einfügen vollständig umgangen werden.
Element mit Status verschieben
Verwenden Sie moveBefore() genau wie insertBefore(). Es sind zwei Argumente erforderlich: der zu verschiebende Knoten und ein Referenzknoten, vor dem der Knoten eingefügt werden soll (oder null, um ihn am Ende des neuen übergeordneten Knotens anzuhängen).
const newParent = document.getElementById('new-parent');
const elementWithState = document.getElementById('iframe-or-focused-input');
// MANDATORY: Use moveBefore to preserve state.
// Passing null as the second argument appends the element to the end of newParent.
newParent.moveBefore(elementWithState, null);
Benutzerdefinierte Elemente (Webkomponenten) verschieben
Wenn Sie benutzerdefinierte Elemente mit moveBefore() verschieben, werden die Lebenszyklusmethoden connectedCallback und disconnectedCallback nicht ausgelöst.
Wenn Ihr benutzerdefiniertes Element beim Verschieben eine bestimmte Logik ausführen muss, implementieren Sie die Methode connectedMoveCallback() in der Definition des benutzerdefinierten Elements.
class MyCustomElement extends HTMLElement {
connectedCallback() {
// Runs on initial insertion.
}
connectedMoveCallback() {
// Runs when the element is moved via moveBefore().
// Use this to update state that depends on the new DOM location.
}
}
Fallback-Strategien
Da moveBefore() eine progressive Verbesserung ist, MÜSSEN Sie die Feature-Erkennung verwenden, bevor Sie sie aufrufen. Für ältere Browser müssen Sie auf herkömmliche insertBefore()- oder appendChild()-Vorgänge zurückgreifen.
const targetParent = document.getElementById('target-container');
const nodeToMove = document.getElementById('moving-element');
// Check if moveBefore is supported on the Element prototype
if ('moveBefore' in Element.prototype) {
targetParent.moveBefore(nodeToMove, null);
} else {
// Fallback: traditional move.
// Note: This WILL reset <iframe>, animation, and focus state in unsupported browsers.
targetParent.insertBefore(nodeToMove, null);
}