Element: moveBefore() Methode

Limited availability

This feature is not Baseline because it does not work in some of the most widely-used browsers.

Die moveBefore() Methode des Element-Interfaces verschiebt einen angegebenen Node als direktes Kind innerhalb des aufrufenden Knotens vor einen gegebenen Referenzknoten.

Syntax

js
moveBefore(movedNode, referenceNode)

Parameter

movedNode

Ein Node, der den zu verschiebenden Knoten repräsentiert. Beachten Sie, dass dies ein Element oder ein CharacterData-Knoten sein muss.

referenceNode

Ein Node, vor dem movedNode bewegt wird, oder null. Ist der Wert null, wird movedNode am Ende der Kindknoten des aufrufenden Knotens eingefügt.

Rückgabewert

Keiner (undefined).

Ausnahmen

HierarchyRequestError TypeError

Wird in einer der folgenden Situationen ausgelöst:

  • Der angegebene movedNode ist nicht Teil des DOM, und Sie versuchen, ihn in einen Knoten zu verschieben, der Teil des DOM ist, oder umgekehrt.
  • Der angegebene movedNode ist ein Vorfahre des Elements, auf dem moveBefore() aufgerufen wird.
  • Sie versuchen, movedNode zwischen zwei verschiedenen Dokumenten zu verschieben.
  • Der angegebene movedNode ist kein Element oder CharacterData-Knoten.
NotFoundError TypeError

Der angegebene referenceNode ist kein Kind des Knotens, auf dem Sie moveBefore() aufrufen, also des Knotens, in den Sie movedNode verschieben wollen.

TypeError TypeError

Das zweite Argument wurde nicht angegeben.

Beschreibung

Die moveBefore()-Methode verschiebt einen angegebenen Knoten an eine neue Stelle im DOM. Sie bietet ähnliche Funktionalität wie die Node.insertBefore()-Methode, entfernt und fügt den Knoten jedoch nicht erneut ein. Dies bedeutet, dass der Zustand des Knotens (der zurückgesetzt würde, wenn er mit insertBefore() und ähnlichen Mechanismen verschoben würde) nach dem Verschieben erhalten bleibt. Zu diesen Zuständen gehören:

Der Wiedergabestatus von <video> und <audio>-Elementen ist nicht in der obigen Liste enthalten, da diese Elemente ihren Zustand behalten, wenn sie entfernt und wieder eingefügt werden, unabhängig vom verwendeten Mechanismus.

Beim Beobachten von Änderungen am DOM mit einem MutationObserver werden mit moveBefore() verschobene Knoten als entfernter Knoten und als hinzugefügter Knoten registriert.

moveBefore() Einschränkungen

Es gibt einige Einschränkungen, die bei der Verwendung von moveBefore() zu beachten sind:

  • Es funktioniert nur, wenn Sie einen Knoten innerhalb desselben Dokuments verschieben.
  • Es funktioniert nicht, wenn Sie versuchen, einen Knoten zu verschieben, der nicht mit dem DOM verbunden ist, zu einem bereits verbundenen Elternknoten, oder umgekehrt.

In solchen Fällen schlägt moveBefore() mit einem HierarchyRequestError-Fehler fehl. Wenn die obigen Einschränkungen Anforderungen für Ihren speziellen Anwendungsfall darstellen, sollten Sie stattdessen Node.insertBefore() verwenden, oder try...catch verwenden, um die Fehler zu behandeln, die aus solchen Fällen resultieren.

Verschiebung von benutzerdefinierten Elementen unter Erhaltung des Zustands

Jedes Mal, wenn die Position eines benutzerdefinierten Elements im DOM durch Element.moveBefore() oder ähnliche Methoden wie Node.insertBefore() aktualisiert wird, werden seine disconnectedCallback()- und connectedCallback()-Lebenszyklus-Callbacks ausgeführt. Da diese Callbacks typischerweise verwendet werden, um jeglichen erforderlichen Initialisierungs- oder Reinigungscode zu implementieren, der zu Beginn oder am Ende des Lebenszyklus des Elements ausgeführt wird, kann das Ausführen dieser Callbacks, wenn das Element verschoben (und nicht entfernt oder eingefügt) wird, Probleme mit seinem Zustand verursachen.

Sie können das connectedMoveCallback()-Callback verwenden, um den Zustand eines benutzerdefinierten Elements zu erhalten. Wenn Sie moveBefore() verwenden, um ein benutzerdefiniertes Element zu verschieben, wird connectedMoveCallback() anstelle von connectedCallback() und disconnectedCallback() ausgeführt.

Siehe Verschieben von benutzerdefinierten Elementen für weitere Informationen.

Beispiele

Grundlegende Nutzung von moveBefore()

In diesem Demo veranschaulichen wir die grundlegende Nutzung von moveBefore().

HTML

Das HTML enthält ein <article>-Element, das ein <div>-Element und zwei <section>-Elemente beinhaltet. Das <div> enthält einen <button>, den wir später verwenden, um es zu verschieben.

html
<article id="wrapper">
  <div id="mover">
    <button>Move me!</button>
  </div>
  <section id="section1">
    <h2>Section 1</h2>
  </section>
  <section id="section2">
    <h2>Section 2</h2>
  </section>
</article>

CSS

Wir bieten einige grundlegende Stile für das Aussehen und den Abstand der Boxen und verwenden das Flexbox-Layout, um deren Inhalt zu zentrieren.

css
#section1,
#section2,
#mover {
  width: 200px;
  height: 80px;
  border: 5px solid rgb(0 0 0 / 0.25);
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
}

#section1,
#section2 {
  background-color: hotpink;
}

#mover {
  background-color: orange;
}

JavaScript

In unserem Skript hängen wir einen Klick-Event-Listener an den <button> mittels addEventListener() an. Wenn der Button geklickt wird, prüfen wir, ob das nextElementSibling unseres mover-<div> das erste <section>-Element ist. Falls ja, rufen wir moveBefore() im wrapper-<article> auf und geben an, dass das <div> vor dem zweiten <section> bewegt wird. Andernfalls verwenden wir moveBefore(), um das <div> vor das erste <section> zu verschieben.

js
const wrapper = document.getElementById("wrapper");
const section1 = document.getElementById("section1");
const section2 = document.getElementById("section2");
const mover = document.getElementById("mover");
const moveBtn = document.querySelector("button");

moveBtn.addEventListener("click", () => {
  if (mover.nextElementSibling === section1) {
    wrapper.moveBefore(mover, section2);
  } else {
    wrapper.moveBefore(mover, section1);
  }
});

Ergebnis

Das gerenderte Beispiel sieht so aus:

Versuchen Sie, den <button> einige Male zu klicken und beobachten Sie, wie er zwischen den beiden Positionen wechselt.

Demonstration der Zustandserhaltung

In diesem Demo bieten wir mehrere Mechanismen, um ein <div>-Element mit einem YouTube-Embed zwischen zwei verschiedenen Containern zu verschieben, und demonstrieren, wie moveBefore() den Wiedergabestatus des Embeds bewahrt, aber die anderen Mechanismen nicht.

HTML

Das HTML enthält ein <article>-Element mit zwei <section>-Elementen. Das erste <section>-Element enthält ein <div>-Element mit dem YouTube-Embed-Code. Wir haben auch ein <div>-Element, das drei <button>-Elemente enthält, denen wir später mit JavaScript Funktionalitäten hinzufügen, um das Embed-<div> zwischen den Abschnitten zu verschieben.

html
<article id="wrapper">
  <section id="section1">
    <div id="mover">
      <iframe
        width="300"
        height="200"
        src="https://www.youtube.com/embed/XvoENpR9cCQ?si=o2i6MvxugD-O5yyv"
        title="YouTube video player"
        frameborder="0"
        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
        referrerpolicy="strict-origin-when-cross-origin"
        allowfullscreen></iframe>
    </div>
  </section>
  <section id="section2"></section>
</article>
<div id="controls">
  <button id="move-before">move with <code>moveBefore()</code></button>
  <button id="insertbefore">move with <code>insertBefore()</code></button>
  <button id="prepend">move with <code>prepend()</code></button>
</div>

CSS

Wir verwenden das Flexbox-Layout für das Layout, um die beiden <section>-Elemente nebeneinander zu platzieren und die Buttons gleichmäßig innerhalb des controls-<div> zu verteilen.

css
#wrapper,
#controls {
  width: 100%;
  display: flex;
}

#wrapper {
  margin-bottom: 10px;
}

section {
  flex: 1;
  padding: 10px;
}

#controls {
  display: flex;
  justify-content: space-around;
}

#section1 {
  background-color: hotpink;
}

#section2 {
  background-color: orange;
}

#mover {
  max-width: 100%;
  background-color: black;
}

JavaScript

In unserem Skript hängen wir click-Event-Listener an jedem <button> mittels addEventListener() an. Wenn die Buttons geklickt werden, prüfen wir, welches <section>-Element das parentElement unseres Embed-<div> ist, und verwenden dann die entsprechende Funktion (moveBefore(), insertBefore(), oder prepend()), um es im anderen <section>-Element zu verschieben.

js
const section1 = document.getElementById("section1");
const section2 = document.getElementById("section2");
const mover = document.getElementById("mover");
const moveBeforeBtn = document.getElementById("move-before");
const insertbeforeBtn = document.getElementById("insertbefore");
const prependBtn = document.getElementById("prepend");

moveBeforeBtn.addEventListener("click", () => {
  if (mover.parentElement === section1) {
    section2.moveBefore(mover, null);
  } else {
    section1.moveBefore(mover, null);
  }
});

insertbeforeBtn.addEventListener("click", () => {
  if (mover.parentElement === section1) {
    section2.insertBefore(mover, null);
  } else {
    section1.insertBefore(mover, null);
  }
});

prependBtn.addEventListener("click", () => {
  if (mover.parentElement === section1) {
    section2.prepend(mover);
  } else {
    section1.prepend(mover);
  }
});

Ergebnis

Das gerenderte Beispiel sieht so aus:

Versuchen Sie, das YouTube-Embed abzuspielen und dann jeden <button> ein paar Mal zu klicken, um die Bildschirmposition des <div>-Elements von links nach rechts zu wechseln. Beachten Sie, wie im Fall von insertBefore() und prepend() der Embed-Zustand nach jedem Verschieben zurückgesetzt wird, sodass er neu gestartet werden muss. Im Fall von moveBefore() wird der Zustand nach jedem Verschieben jedoch beibehalten.

Spezifikationen

Specification
DOM
# dom-parentnode-movebefore

Browser-Kompatibilität

Siehe auch