Movatterモバイル変換


[0]ホーム

URL:


  1. Web
  2. Web APIs
  3. Element
  4. moveBefore()

Element: moveBefore() method

Limited availability

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

ThemoveBefore() method of theElement interface moves a givenNode inside the invoking node as a direct child, before a given reference node.

Syntax

js
moveBefore(movedNode, referenceNode)

Parameters

movedNode

ANode representing the node to be moved. Note that this must be anElement or aCharacterData node.

referenceNode

ANode thatmovedNode will be moved before, ornull. If the value isnull,movedNode is inserted at the end of the invoking node's child nodes.

Return value

None (undefined).

Exceptions

HierarchyRequestErrorTypeError

Thrown in any of the following situations:

  • The specifiedmovedNode is not part of the DOM, and you are trying to move it inside a node that is part of the DOM, or vice versa.
  • The specifiedmovedNode is an ancestor of the ElementmoveBefore() is being called on.
  • You are trying to movemovedNode between two different documents.
  • The specifiedmovedNode is not anElement orCharacterData node.
NotFoundErrorTypeError

The specifiedreferenceNode is not a child of the node you are callingmoveBefore() on, that is, the node you are trying to movemovedNode inside.

TypeErrorTypeError

The second argument was not supplied.

Description

ThemoveBefore() method moves a given node to a new place in the DOM. It provides similar functionality to theNode.insertBefore() method, except that it doesn't remove and then reinsert the node. This means that the state of the node (which would be reset if moving it withinsertBefore() and similar mechanisms) is preserved after the move. This includes:

The play state of<video> and<audio> elements is not included in the above list, as these elements retain their state when removed and reinserted, regardless of the mechanism used.

When observing changes to the DOM using aMutationObserver, nodes moved withmoveBefore() will be recorded with aremoved node and anadded node.

moveBefore() constraints

There are some constraints to be aware of when usingmoveBefore():

  • It can only work when moving a node within the same document.
  • It won't work if you try to move a node that is not connected to the DOM to an already connected parent, or vice versa.

In such cases,moveBefore() will fail with aHierarchyRequestError exception. If the above constraints are requirements for your particular use case, you should useNode.insertBefore() instead, or usetry...catch to handle the errors that arise from such cases.

Moving custom elements while preserving state

Each time acustom element's position in the DOM is updated viaElement.moveBefore(), or similar methods such asNode.insertBefore(), itsdisconnectedCallback() andconnectedCallback() lifecycle callbacks are fired. Since these callbacks are typically used to implement any required initialization or cleanup code to run at the start or end of the element's lifecycle, running them when the element is moved (rather than removed or inserted) may cause problems with its state.

You can use theconnectedMoveCallback() callback to preserve a custom element's state. When usingmoveBefore() to move a custom element,connectedMoveCallback() is run instead ofconnectedCallback() anddisconnectedCallback().

SeeMoving custom elements for further information.

Examples

BasicmoveBefore() usage

In this demo we illustrate basic usage ofmoveBefore().

HTML

The HTML features an<article> element containing a<div> element and two<section> elements. The<div> contains a<button>, which we later use to move it.

html
<article>  <div>    <button>Move me!</button>  </div>  <section>    <h2>Section 1</h2>  </section>  <section>    <h2>Section 2</h2>  </section></article>

CSS

We provide some rudimentary styling for the look and feel and spacing of the boxes, and useflexbox to center their content.

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 our script, we attach a click event listener to the<button> viaaddEventListener(). When the button is clicked, we check whether thenextElementSibling of ourmover<div> is the first<section> element. If so, we invokemoveBefore() on thewrapper<article> and specify to move the<div> before the second<section>. If not, we usemoveBefore() to move the<div> before the first<section>.

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);  }});

Result

The rendered example looks like this:

Try clicking the<button> a few times and note how it toggles between the two positions.

Demonstrating state preservation

In this demo we provide multiple mechanisms to move a<div> element containing a YouTube embed between two different containers, demonstrating howmoveBefore() preserves the play state of the embed, but the other mechanisms do not.

HTML

The HTML features an<article> element containing two<section> elements. The first<section> element contains a<div> element containing the YouTube embed code. We also have a<div> element containing three<button> elements, to which we will add functionality to move the embed<div> between sections via JavaScript later on.

html
<article>  <section>    <div>      <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></section></article><div>  <button>move with <code>moveBefore()</code></button>  <button>move with <code>insertBefore()</code></button>  <button>move with <code>prepend()</code></button></div>

CSS

We useflexbox for the layout to make the two<section> elements sit side-by-side, and space the buttons evenly inside thecontrols<div>.

css
#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 our script, we attachclick event listeners to each<button> viaaddEventListener(). When the buttons are clicked, we check which<section> element is theparentElement of our embed<div>, and then use the relevant function (moveBefore(),insertBefore(), orprepend()) to move it inside theother<section> element.

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);  }});

Result

The rendered example looks like this:

Try playing the YouTube embed and then clicking each<button> a couple of times to toggle the<div> element screen position from left to right. Note how, in the case ofinsertBefore() andprepend(), the embed state is reset after each move so it needs to be restarted. However, in the case ofmoveBefore(), the state is preserved after each move.

Specifications

Specification
DOM
# dom-parentnode-movebefore

Browser compatibility

See also

Help improve MDN

Learn how to contribute

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2025 Movatter.jp