Element: Methode moveBefore()
Eingeschränkt verfügbar
Diese Funktion ist nicht Baseline, da sie in einigen der am weitesten verbreiteten Browser nicht funktioniert.
Want more browser support for this feature? Tell us why.
Die Methode moveBefore() des Interfaces Element verschiebt einen angegebenen Node innerhalb des aufrufenden Knotens als direktes Kindelement vor einen angegebenen Referenzknoten.
Syntax
moveBefore(movedNode, referenceNode)
Parameter
movedNode-
Ein
Node, der den zu verschiebenden Knoten darstellt. Beachten Sie, dass dies einElement- oderCharacterData-Knoten sein muss. referenceNode-
Ein
Node, vor denmovedNodeverschoben wird, odernull. Wenn der Wertnullist, wirdmovedNodeam Ende der Kindknoten des aufrufenden Knotens eingefügt.
Rückgabewert
Keiner (undefined).
Ausnahmen
HierarchyRequestErrorDOMException-
Wird in einer der folgenden Situationen ausgelöst:
- Der angegebene
movedNodeist nicht Teil des DOM und Sie versuchen, ihn in einen Knoten zu verschieben, der Teil des DOM ist, oder umgekehrt. - Der angegebene
movedNodeist ein Vorgänger desElement, auf demmoveBefore()aufgerufen wird. - Sie versuchen,
movedNodezwischen zwei verschiedenen Dokumenten zu verschieben. - Der angegebene
movedNodeist keinElement- oderCharacterData-Knoten.
- Der angegebene
NotFoundErrorDOMException-
Der angegebene
referenceNodeist kein Kindknoten des Knotens, auf dem SiemoveBefore()aufrufen, also des Knotens, in den SiemovedNodezu verschieben versuchen. TypeError-
Das zweite Argument wurde nicht angegeben.
Beschreibung
Die Methode moveBefore() verschiebt einen angegebenen Knoten an eine neue Position im DOM. Sie bietet eine ähnliche Funktionalität wie die Methode Node.insertBefore(), entfernt den Knoten jedoch nicht und fügt ihn anschließend wieder ein. Das bedeutet, dass der Zustand des Knotens (der beim Verschieben mit insertBefore() und ähnlichen Mechanismen zurückgesetzt würde) nach dem Verschieben erhalten bleibt. Dazu gehören:
- Der Zustand von Animationen und Transitions.
- Der Ladezustand von
<iframe>. - Interaktivitätszustände (zum Beispiel
:focusund:active). - Der Zustand eines Vollbild-Elements.
- Der Offen-/Geschlossen-Zustand von Popovers.
- Der modale Zustand von
<dialog>-Elementen (modale Dialoge werden nicht geschlossen).
Der Wiedergabezustand von <video>- und <audio>-Elementen ist nicht in der obigen Liste enthalten, da diese Elemente ihren Zustand beim Entfernen und erneuten Einfügen unabhängig vom verwendeten Mechanismus beibehalten.
Wenn Sie Änderungen am DOM mithilfe eines MutationObserver beobachten, werden mit moveBefore() verschobene Knoten mit einem entfernten Knoten und einem hinzugefügten Knoten erfasst.
Einschränkungen von moveBefore()
Bei der Verwendung von moveBefore() sind einige Einschränkungen zu beachten:
- Es funktioniert nur beim Verschieben eines Knotens innerhalb desselben Dokuments.
- Es funktioniert nicht, wenn Sie versuchen, einen Knoten, der nicht mit dem DOM verbunden ist, in ein bereits verbundenes Elternelement zu verschieben, oder umgekehrt.
In solchen Fällen schlägt moveBefore() mit einer HierarchyRequestError-Ausnahme fehl. Wenn die oben genannten Einschränkungen Anforderungen für Ihren speziellen Anwendungsfall sind, sollten Sie stattdessen Node.insertBefore() verwenden oder try...catch einsetzen, um die Fehler zu behandeln, die in solchen Fällen auftreten.
Verschieben benutzerdefinierter Elemente unter Beibehaltung des Zustands
Jedes Mal, wenn die Position eines benutzerdefinierten Elements im DOM über Element.moveBefore() oder ähnliche Methoden wie Node.insertBefore() aktualisiert wird, werden seine Lebenszyklus-Callbacks disconnectedCallback() und connectedCallback() ausgelöst. Da diese Callbacks typischerweise verwendet werden, um erforderlichen Initialisierungs- oder Bereinigungscode auszuführen, der am Anfang oder Ende des Lebenszyklus des Elements ausgeführt werden soll, kann ihre Ausführung beim Verschieben des Elements (statt beim Entfernen oder Einfügen) Probleme mit seinem Zustand verursachen.
Sie können den Callback connectedMoveCallback() verwenden, um den Zustand eines benutzerdefinierten Elements beizubehalten. Wenn Sie moveBefore() verwenden, um ein benutzerdefiniertes Element zu verschieben, wird connectedMoveCallback() anstelle von connectedCallback() und disconnectedCallback() ausgeführt.
Weitere Informationen finden Sie unter Verschieben benutzerdefinierter Elemente.
Beispiele
>Grundlegende Verwendung von moveBefore()
In dieser Demo veranschaulichen wir die grundlegende Verwendung von moveBefore().
HTML
Das HTML enthält ein <article>-Element mit einem <div>-Element und zwei <section>-Elementen. Das <div> enthält ein <button>, das wir später verwenden, um es zu verschieben.
<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 stellen einige einfache Stilregeln für das Erscheinungsbild und die Abstände der Kästen bereit und verwenden Flexbox, um deren Inhalt zu zentrieren.
#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 fügen wir dem <button> über addEventListener() einen click-Event-Listener hinzu. Wenn auf die Schaltfläche geklickt wird, überprüfen wir, ob der nextElementSibling unseres mover-<div> das erste <section>-Element ist. Falls ja, rufen wir moveBefore() auf dem wrapper-<article> auf und geben an, dass das <div> vor das zweite <section> verschoben werden soll. Andernfalls verwenden wir moveBefore(), um das <div> vor das erste <section> zu verschieben.
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 folgendermaßen aus:
Klicken Sie einige Male auf den <button> und beachten Sie, wie er zwischen den beiden Positionen wechselt.
Demonstration der Zustandserhaltung
In dieser Demo stellen wir mehrere Mechanismen bereit, um ein <div>-Element mit einer eingebetteten YouTube-Anwendung zwischen zwei verschiedenen Containern zu verschieben. Dabei wird gezeigt, wie moveBefore() den Wiedergabezustand der Einbettung beibehält, die anderen Mechanismen jedoch nicht.
HTML
Das HTML enthält ein <article>-Element mit zwei <section>-Elementen. Das erste <section>-Element enthält ein <div>-Element, das den YouTube-Einbettungscode enthält. Außerdem haben wir ein <div>-Element mit drei <button>-Elementen, denen wir später per JavaScript Funktionalität hinzufügen werden, um das eingebettete <div> zwischen den Abschnitten zu verschieben.
<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"
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
Für das Layout verwenden wir Flexbox, damit die beiden <section>-Elemente nebeneinander stehen, und verteilen die Schaltflächen gleichmäßig innerhalb des controls-<div>.
#wrapper,
#controls {
width: 100%;
display: flex;
}
#wrapper {
margin-bottom: 10px;
}
iframe {
border: none;
}
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 fügen wir über addEventListener() jedem <button> click-Event-Listener hinzu. Wenn auf die Schaltflächen geklickt wird, überprüfen wir, welches <section>-Element das parentElement unseres eingebetteten <div> ist, und verwenden dann die entsprechende Funktion (moveBefore(), insertBefore() oder prepend()), um es innerhalb des anderen <section>-Elements zu verschieben.
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 folgendermaßen aus:
Starten Sie die Wiedergabe der YouTube-Einbettung und klicken Sie dann einige Male auf jeden <button>, um die Bildschirmposition des <div>-Elements von links nach rechts umzuschalten. Beachten Sie, dass bei insertBefore() und prepend() der Zustand der Einbettung nach jeder Verschiebung zurückgesetzt wird und sie daher neu gestartet werden muss. Bei moveBefore() bleibt der Zustand nach jeder Verschiebung jedoch erhalten.
Spezifikationen
| Spezifikation |
|---|
| DOM> # dom-parentnode-movebefore> |