Start · Sprachen · JavaScript · Referenz · Element.moveBefore()

Element.moveBefore()

Methode

Verschiebt einen Knoten als direktes Kind des aufrufenden Elements vor <code>referenceNode</code>, ohne ihn zu entfernen und neu einzufügen. Sein Zustand bleibt dabei erhalten.

seit JavaScript Chrome/Edge 133+, Firefox 144+; Safari noch nicht Kategorie: webapi

Signatur

Element.prototype.moveBefore(movedNode, referenceNode)

Beschreibung

moveBefore() verschiebt einen Knoten, der bereits im selben DOM-Baum hängt, an eine neue Stelle. Er wird dann direktes Kind des aufrufenden Elements und steht vor referenceNode. Ist referenceNode gleich null, landet der Knoten am Ende der Kindliste.

Der Unterschied zu insertBefore() und appendChild() ist der erhaltene Zustand. Die klassischen Methoden entfernen den Knoten intern und fügen ihn neu ein. Dabei gehen Zustände verloren: Ein <iframe> lädt neu, ein <video> pausiert, und Fokus, laufende CSS-Animationen und -Übergänge, offene Popover, modale Dialoge und der Vollbildmodus werden zurückgesetzt. moveBefore() verschiebt den Knoten dagegen atomar, sodass all das erhalten bleibt.

Typische Einsatzfälle:

  • Sortierbare Listen per Drag & Drop
  • Layout-Wechsel, z. B. ein Video-Player wandert von der Hauptansicht in eine Seitenleiste
  • Frameworks, die beim Abgleich des DOM (Reconciliation) Elemente umsortieren

Bei Custom Elements ruft der Browser statt disconnectedCallback/connectedCallback die Methode connectedMoveCallback() auf, sofern sie definiert ist. Dieselbe Methode gibt es auch auf Document und DocumentFragment.

Parameter

Name Typ Default Beschreibung
$movedNode Pflicht Element | CharacterData Der Knoten, der verschoben werden soll: ein Element oder ein Text- bzw. Kommentarknoten. Er muss dieselbe Wurzel haben wie das Ziel-Element (einschließlich Shadow-Wurzeln), also z. B. im selben verbundenen Dokument hängen.
$referenceNode Pflicht Node | null Das Kind des aufrufenden Elements, vor das movedNode gesetzt wird. Bei null wird movedNode als letztes Kind eingefügt. Der Parameter muss übergeben werden, auch wenn er null ist.

Rückgabewert

Typ
undefined
Beschreibung
Kein Rückgabewert. Das DOM wird direkt verändert.

Beispiele

Listeneintrag nach oben verschieben

// <ul id="todo"><li>A</li><li>B</li><li>C</li></ul>
const list = document.querySelector('#todo');
const [first, , third] = list.children;

// "C" vor "A" setzen
list.moveBefore(third, first);

console.log([...list.children].map(li => li.textContent).join(', '));
C, A, B

Laufendes Video ohne Unterbrechung in die Seitenleiste verschieben (mit Fallback)

const video = document.querySelector('#player');
const sidebar = document.querySelector('#sidebar');

const moveNode = (parent, node, ref = null) => {
  if ('moveBefore' in Element.prototype) {
    parent.moveBefore(node, ref);   // Wiedergabe läuft weiter
  } else {
    parent.insertBefore(node, ref); // Fallback: Video pausiert
  }
};

document.querySelector('#compact').addEventListener('click', () => {
  moveNode(sidebar, video); // null → ans Ende der Seitenleiste
  console.log('Pausiert?', video.paused);
});
Pausiert? false

Custom Element mit connectedMoveCallback

class LiveClock extends HTMLElement {
  connectedCallback() {
    this.timer = setInterval(() => {
      this.textContent = new Date().toLocaleTimeString('de-DE');
    }, 1000);
    console.log('gestartet');
  }
  disconnectedCallback() {
    clearInterval(this.timer);
    console.log('gestoppt');
  }
  // Wird bei moveBefore() statt disconnected/connected aufgerufen
  connectedMoveCallback() {
    console.log('verschoben – Timer läuft weiter');
  }
}
customElements.define('live-clock', LiveClock);

const clock = document.createElement('live-clock');
document.body.append(clock);
document.querySelector('header').moveBefore(clock, null);
gestartet verschoben – Timer läuft weiter

Fehler bei getrennten Knoten abfangen

const target = document.querySelector('#target');
const fresh = document.createElement('p'); // noch nicht im Dokument

try {
  target.moveBefore(fresh, null);
} catch (err) {
  console.log(err.name);
  target.insertBefore(fresh, null); // normales Einfügen
}
HierarchyRequestError

// Wichtig · Fallstricke

  • Browser-Unterstützung: Die Methode ist neu: Chromium ab 133 und Firefox ab 144 unterstützen sie, Safari bisher nicht. Prüfe vor dem Aufruf mit 'moveBefore' in Element.prototype, ob sie vorhanden ist, und weiche sonst auf insertBefore() aus.
  • HierarchyRequestError: Dieser Fehler tritt auf, wenn movedNode und das Ziel-Element nicht dieselbe Wurzel haben. Das betrifft zum Beispiel einen frisch erzeugten, noch nicht eingehängten Knoten, einen Knoten aus einem anderen Dokument oder einen Knoten aus einem anderen Shadow-Baum. Derselbe Fehler kommt, wenn movedNode kein Element und kein CharacterData-Knoten ist oder wenn ein Knoten in sich selbst bzw. in eines seiner Kinder verschoben würde. Ein verschobener Knoten kann also nie zum ersten Mal ins Dokument kommen; dafür braucht es append() oder insertBefore().
  • NotFoundError: Dieser Fehler tritt auf, wenn referenceNode kein direktes Kind des aufrufenden Elements ist.
  • Der zweite Parameter ist Pflicht. Wer ans Ende verschieben will, übergibt ausdrücklich null.
  • MutationObserver meldet die Verschiebung weiterhin als Entfernen und Hinzufügen des Knotens.
  • Bei Custom Elements ohne connectedMoveCallback laufen weiterhin disconnectedCallback und connectedCallback.