Signatur
Beschreibung
moveBefore() gehört zur „Atomic Move“-API. Mit ihr lässt sich ein Knoten innerhalb eines Baums umsetzen, ohne ihn erst zu entfernen und dann neu einzufügen. Das klassische insertBefore() macht genau das: Es entfernt den Knoten und fügt ihn wieder ein. Dadurch gehen Zustände verloren, etwa der Fokus, laufende CSS-Animationen und Transitions oder der geladene Inhalt eines <iframe>. moveBefore() behält diese Zustände bei.
Beim DocumentFragment gilt eine wichtige Einschränkung: Der zu verschiebende Knoten muss bereits im selben Fragment liegen. Die Methode prüft, ob Knoten und Fragment dieselbe Wurzel haben (die „shadow-including root“). Ein Fragment ist immer seine eigene Wurzel. Deshalb lassen sich nur Knoten umsetzen, die schon darin stecken, entweder als direkte Kinder oder tiefer verschachtelt. Knoten aus dem Dokument oder aus einem anderen Fragment kann man so nicht holen.
Man nutzt die Methode, um den Inhalt eines Fragments umzusortieren, bevor er ins Dokument kommt, oder um einen tiefer verschachtelten Knoten auf die oberste Ebene zu holen. Für Fragmente ist der Nutzen kleiner als im Live-DOM, weil Fragmente nicht mit dem Dokument verbunden sind. Die Methode ist aber Teil der gemeinsamen Schnittstelle, die es auch bei Element und Document gibt.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $movedNode Pflicht | Element | CharacterData | Der Knoten, der verschoben wird. Erlaubt sind nur Elemente und Zeichendaten-Knoten (Text, Comment). Der Knoten muss schon im selben Fragment liegen. |
|
| $referenceNode Pflicht | Node | null | Das direkte Kind des Fragments, vor dem movedNode eingefügt wird. Bei null landet der Knoten als letztes Kind am Ende. Das Argument ist Pflicht und darf nicht weggelassen werden. |
Rückgabewert
Beispiele
Einträge im Fragment umsortieren, bevor sie ins Dokument kommen
const fragment = document.createDocumentFragment();
['Banane', 'Apfel', 'Kirsche'].forEach((name) => {
const li = document.createElement('li');
li.textContent = name;
fragment.append(li);
});
// "Apfel" (2. Kind) vor "Banane" (1. Kind) setzen
const [banane, apfel] = fragment.children;
fragment.moveBefore(apfel, banane);
console.log([...fragment.children].map((li) => li.textContent));
document.querySelector('ul').append(fragment);
Verschachtelten Knoten mit null ans Ende holen
const fragment = document.createDocumentFragment();
const wrapper = document.createElement('div');
const hinweis = document.createElement('p');
hinweis.textContent = 'Hinweis';
wrapper.append(hinweis);
fragment.append(wrapper, document.createElement('footer'));
// <p> liegt im selben Fragment (im div) und wird direktes Kind am Ende
fragment.moveBefore(hinweis, null);
console.log([...fragment.childNodes].map((n) => n.nodeName));
Funktionsprüfung mit Rückfall auf insertBefore()
const moveInto = (parent, node, ref) => {
if ('moveBefore' in parent) {
try {
parent.moveBefore(node, ref);
return;
} catch (err) {
// z. B. HierarchyRequestError: Knoten liegt nicht im Fragment
if (err.name !== 'HierarchyRequestError') throw err;
}
}
parent.insertBefore(node, ref);
};
const fragment = document.createDocumentFragment();
const a = document.createElement('span');
const b = document.createElement('em');
fragment.append(a, b);
moveInto(fragment, b, a);
console.log(fragment.firstChild.nodeName);
Fehlerfall: Knoten stammt nicht aus dem Fragment
const fragment = document.createDocumentFragment();
const fremd = document.createElement('div'); // nicht im Fragment
try {
fragment.moveBefore(fremd, null);
} catch (err) {
console.log(err.name);
}
// Wichtig · Fallstricke
Fehler, die auftreten können:
HierarchyRequestError:movedNodeliegt nicht im selben Fragment (andere Wurzel). Dasselbe gilt, wenn er kein Element und keinCharacterData-Knoten ist oder wenn er ein Vorfahre des Ziels wäre.NotFoundError:referenceNodeist wedernullnoch ein direktes Kind des Fragments.TypeError: Das zweite Argument fehlt. Anders als bei manchen DOM-Methoden mussreferenceNodeausdrücklich übergeben werden, notfalls alsnull.
Wann man insertBefore() nimmt: Um Knoten von außen in ein Fragment zu holen, bleiben insertBefore(), append() oder prepend() der richtige Weg. moveBefore() taugt nur für Verschiebungen innerhalb desselben Baums.
MutationObserver: Ein Beobachter erhält auch bei einem Verschieben Mutations-Einträge für das Entfernen und das Hinzufügen. Custom Elements mit einem connectedMoveCallback() bekommen diesen Callback statt disconnectedCallback und connectedCallback.
Kompatibilität: Die Methode ist noch relativ neu. Sie gibt es in Chromium-Browsern ab Version 133, in anderen Engines teils noch nicht. Vor dem Einsatz sollte man mit 'moveBefore' in fragment prüfen, ob sie verfügbar ist, und einen Rückfall auf insertBefore() vorsehen.