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
moveBefore(movedNode, referenceNode)
Parameter
movedNode
-
Ein
Node
, der den zu verschiebenden Knoten repräsentiert. Beachten Sie, dass dies einElement
oder einCharacterData
-Knoten sein muss. referenceNode
-
Ein
Node
, vor demmovedNode
bewegt wird, odernull
. Ist der Wertnull
, wirdmovedNode
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 demmoveBefore()
aufgerufen wird. - Sie versuchen,
movedNode
zwischen zwei verschiedenen Dokumenten zu verschieben. - Der angegebene
movedNode
ist keinElement
oderCharacterData
-Knoten.
- Der angegebene
NotFoundError
TypeError
-
Der angegebene
referenceNode
ist kein Kind des Knotens, auf dem SiemoveBefore()
aufrufen, also des Knotens, in den SiemovedNode
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:
- Animation und Transition-Zustand.
<iframe>
-Ladezustand.- Interaktivitätszustände (z. B.
:focus
und:active
). - Fullscreen-Elementzustand.
- Offen-/Geschlossen-Zustand von Popovers.
- Modalzustand von
<dialog>
-Elementen (modale Dialoge werden nicht geschlossen).
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.
<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.
#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.
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.
<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.
#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.
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 |