Element : méthode moveBefore()
Disponibilité limitée
Cette fonctionnalité n'est pas Compatible car elle ne fonctionne pas dans certains des navigateurs les plus utilisés.
Want more browser support for this feature? Tell us why.
La méthode moveBefore() de l'interface Element déplace un nœud (Node) donné à l'intérieur du nœud appelant en tant qu'enfant direct, avant un nœud de référence donné.
Syntaxe
moveBefore(movedNode, referenceNode)
Paramètres
movedNode-
Un objet
Nodereprésentant le nœud à déplacer. Notez qu'il doit s'agir d'un nœudElementouCharacterData. referenceNode-
Un objet
Nodedevant lequelmovedNodeest déplacé, ounull. Si la valeur estnull,movedNodeest inséré à la fin des nœuds enfants du nœud appelant.
Valeur de retour
Aucune (undefined).
Exceptions
HierarchyRequestErrorTypeError-
Levée dans l'une des situations suivantes :
- Le
movedNodedéfini ne fait pas partie du DOM, et vous essayez de le déplacer à l'intérieur d'un nœud qui fait partie du DOM, ou vice versa. - Le
movedNodedéfini est un ancêtre de l'élément sur lequelmoveBefore()est appelé. - Vous essayez de déplacer
movedNodeentre deux documents différents. - Le
movedNodedéfini n'est pas un nœudElementouCharacterData.
- Le
NotFoundErrorTypeError-
Le
referenceNodedéfini n'est pas un enfant du nœud sur lequel vous appelezmoveBefore(), c'est-à-dire le nœud dans lequel vous essayez de déplacermovedNode. TypeErrorTypeError-
Le deuxième argument n'a pas été fourni.
Description
La méthode moveBefore() déplace un nœud donné vers un nouvel emplacement dans le DOM. Elle fournit une fonctionnalité similaire à la méthode Node.insertBefore(), sauf qu'elle ne supprime pas puis ne réinsère le nœud. Cela signifie que l'état du nœud (qui serait réinitialisé si on le déplaçait avec insertBefore() et des mécanismes similaires) est préservé après le déplacement. Cela inclut :
- L'état d'animation et de transition.
- L'état de chargement d'un
<iframe>. - Les états d'interactivité (par exemple,
:focuset:active). - L'état en plein écran d'un élément.
- L'état d'ouverture/fermeture des fenêtres contextuelles.
- L'état bloquant des éléments
<dialog>(les boîtes de dialogue bloquantes ne sont pas fermées).
L'état de lecture des éléments HTML <video> et <audio> n'est pas inclus dans la liste ci-dessus, car ces éléments conservent leur état lorsqu'ils sont retirés et réinsérés, quel que soit le mécanisme utilisé.
Lors de l'observation des modifications du DOM à l'aide d'un MutationObserver, les nœuds déplacés avec moveBefore() sont enregistrés avec un nœud supprimé et un nœud ajouté.
Contraintes de moveBefore()
Il existe certaines contraintes à connaître lors de l'utilisation de moveBefore() :
- Il ne peut fonctionner que lors du déplacement d'un nœud au sein du même document.
- Il ne fonctionne pas si vous essayez de déplacer un nœud qui n'est pas connecté au DOM vers un parent déjà connecté, ou vice versa.
Dans de tels cas, moveBefore() échoue avec une exception HierarchyRequestError. Si les contraintes ci-dessus sont des exigences pour votre cas d'utilisation particulier, vous devez utiliser Node.insertBefore() à la place, ou utiliser try...catch pour gérer les erreurs qui surviennent dans de tels cas.
Déplacer les éléments personnalisés tout en préservant leur état
Chaque fois que la position d'un élément personnalisé dans le DOM est mise à jour avec Element.moveBefore(), ou des méthodes similaires telles que Node.insertBefore(), ses rappels de cycle de vie disconnectedCallback() et connectedCallback() sont déclenchés. Comme ces rappels sont généralement utilisés pour implémenter tout code d'initialisation ou de nettoyage nécessaire au début ou à la fin du cycle de vie de l'élément, les exécuter lorsque l'élément est déplacé (plutôt que supprimé ou inséré) peut poser des problèmes avec son état.
Vous pouvez utiliser le rappel connectedMoveCallback() pour préserver l'état d'un élément personnalisé. Lors de l'utilisation de moveBefore() pour déplacer un élément personnalisé, connectedMoveCallback() est exécuté à la place de connectedCallback() et disconnectedCallback().
Voir Déplacer des éléments personnalisés pour plus d'informations.
Exemples
>Utilisation simple de moveBefore()
Dans cette démonstration, nous illustrons l'utilisation de base de moveBefore().
HTML
La fonctionnalité HTML présente un élément <article> contenant un élément <div> et deux éléments <section>. Le <div> contient un <button>, que nous utilisons plus tard pour le déplacer.
<article id="enveloppe">
<div id="deplace">
<button>Déplacez-moi !</button>
</div>
<section id="section1">
<h2>Section 1</h2>
</section>
<section id="section2">
<h2>Section 2</h2>
</section>
</article>
CSS
Nous fournissons un style rudimentaire pour l'apparence et l'espacement des boîtes, et utilisons les boîtes flexibles pour centrer leur contenu.
#section1,
#section2,
#deplace {
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;
}
#deplace {
background-color: orange;
}
JavaScript
Dans notre script, nous attachons un écouteur d'évènement click au <button> avec addEventListener(). Lorsque le bouton est cliqué, nous vérifions si le nextElementSibling de notre <div> deplace est le premier élément <section>. Si c'est le cas, nous invoquons moveBefore() sur <article> enveloppe et spécifions de déplacer le <div> avant le deuxième <section>. Sinon, nous utilisons moveBefore() pour déplacer le <div> avant le premier <section>.
const enveloppe = document.getElementById("enveloppe");
const section1 = document.getElementById("section1");
const section2 = document.getElementById("section2");
const deplace = document.getElementById("deplace");
const btnDeplacer = document.querySelector("button");
btnDeplacer.addEventListener("click", () => {
if (deplace.nextElementSibling === section1) {
enveloppe.moveBefore(deplace, section2);
} else {
enveloppe.moveBefore(deplace, section1);
}
});
Résultat
L'exemple est rendu comme ceci :
Essayez de cliquer sur le <button> plusieurs fois et notez comment il bascule entre les deux positions.
Démontrer la préservation de l'état
Dans cette démonstration, nous fournissons plusieurs mécanismes pour déplacer un élément <div> contenant une intégration YouTube entre deux conteneurs différents, démontrant comment moveBefore() préserve l'état de lecture de l'intégration, tandis que les autres mécanismes ne le font pas.
HTML
Le HTML présente un élément <article> contenant deux éléments <section>. Le premier élément <section> contient un élément <div> contenant le code d'intégration YouTube. Nous avons également un élément <div> contenant trois éléments <button>, auxquels nous ajoutons ultérieurement la fonctionnalité de déplacement de l'élément <div> d'intégration entre les sections avec JavaScript.
<article id="enveloppe">
<section id="section1">
<div id="deplace">
<iframe
width="300"
height="200"
src="https://www.youtube.com/embed/XvoENpR9cCQ?si=o2i6MvxugD-O5yyv"
title="Lecteur vidéo YouTube"
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="controles">
<button id="deplace-avant">déplacer avec <code>moveBefore()</code></button>
<button id="insererAvant">déplacer avec <code>insertBefore()</code></button>
<button id="ajouter-au-debut">déplacer avec <code>prepend()</code></button>
</div>
CSS
Nous utilisons les boîtes flexibles pour la mise en page afin de placer les deux éléments <section> côte à côte et d'espacer uniformément les boutons à l'intérieur du <div> controles.
#enveloppe,
#controles {
width: 100%;
display: flex;
}
#enveloppe {
margin-bottom: 10px;
}
iframe {
border: none;
}
section {
flex: 1;
padding: 10px;
}
#controles {
display: flex;
justify-content: space-around;
}
#section1 {
background-color: hotpink;
}
#section2 {
background-color: orange;
}
#deplace {
max-width: 100%;
background-color: black;
}
JavaScript
Dans notre script, nous attachons des écouteurs d'évènement click à chaque <button> avec addEventListener(). Lorsque les boutons sont cliqué, nous vérifions quel élément <section> est le parentElement de notre <div> d'intégration, puis nous utilisons la fonction appropriée (moveBefore(), insertBefore(), ou prepend()) pour le déplacer à l'intérieur de l'autre élément <section>.
const section1 = document.getElementById("section1");
const section2 = document.getElementById("section2");
const deplace = document.getElementById("deplace");
const btnDeplaceAvant = document.getElementById("deplace-avant");
const btnInsereAvant = document.getElementById("insererAvant");
const btnAjouterAuDebut = document.getElementById("ajouter-au-debut");
btnDeplaceAvant.addEventListener("click", () => {
if (deplace.parentElement === section1) {
section2.moveBefore(deplace, null);
} else {
section1.moveBefore(deplace, null);
}
});
btnInsereAvant.addEventListener("click", () => {
if (deplace.parentElement === section1) {
section2.insertBefore(deplace, null);
} else {
section1.insertBefore(deplace, null);
}
});
btnAjouterAuDebut.addEventListener("click", () => {
if (deplace.parentElement === section1) {
section2.prepend(deplace);
} else {
section1.prepend(deplace);
}
});
Résultat
L'exemple est rendu comme ceci :
Essayez de lire l'intégration YouTube, puis cliquez sur chaque <button> plusieurs fois pour basculer la position de l'élément <div> à l'écran de gauche à droite. Notez comment, dans le cas de insertBefore() et prepend(), l'état de l'intégration est réinitialisé après chaque déplacement, nécessitant un redémarrage. Cependant, dans le cas de moveBefore(), l'état est préservé après chaque déplacement.
Spécifications
| Spécification |
|---|
| DOM> # dom-parentnode-movebefore> |
Compatibilité des navigateurs
Voir aussi
- La méthode
Document.moveBefore() - La méthode
DocumentFragment.moveBefore() - La méthode
Node.insertBefore()