DocumentFragment: moveBefore() 方法
moveBefore() 方法是 DocumentFragment 接口的一个方法,它将一个给定的 Node 作为直接子节点,移动到调用该方法的 DocumentFragment 中,位于一个给定的参考节点之前。
语法
moveBefore(movedNode, referenceNode)
参数
movedNode-
一个
Node,表示要移动的节点。请注意,这必须是一个Element或CharacterData节点。 referenceNode-
movedNode将被移动到的节点,或者null。如果值为null,则movedNode将被插入到调用该方法的DocumentFragment的子节点列表的末尾。
返回值
无(undefined)。
异常
HierarchyRequestErrorTypeError-
在以下任何情况下抛出:
- 指定的
movedNode已经被添加到 DOM 中,而您正试图将其移动到一个DocumentFragment中。 - 您正试图在两个不同的 document fragments 之间移动
movedNode。 - 指定的
movedNode不是Element或CharacterData节点。
- 指定的
NotFoundErrorTypeError-
指定的
referenceNode不是您调用moveBefore()方法的DocumentFragment的子节点,也就是说,您试图将movedNode移动到其中的 fragment。 TypeErrorTypeError-
未提供第二个参数。
描述
moveBefore() 方法将一个给定的节点移动到 DocumentFragment 中的新位置。它提供了与 Node.insertBefore() 方法类似的功能,但它不会删除然后重新插入节点。这意味着在移动后,节点的(如果使用 insertBefore() 和类似机制移动,状态会重置)状态会被保留。这包括:
和 元素的播放状态不包含在上述列表中,因为这些元素在被移除和重新插入时会保留其状态,无论使用何种机制。
当使用 MutationObserver 观察 DOM 变化时,使用 moveBefore() 移动的节点将被记录为 已移除节点 和 已添加节点。
moveBefore() 约束
使用 moveBefore() 时需要注意一些约束:
- 它只能在同一个 document fragment 内移动节点时工作。
- 如果您尝试移动一个已经被添加到 DOM 中的节点到一个
DocumentFragment中,它将无法工作。
在这种情况下,moveBefore() 将抛出 HierarchyRequestError 异常。如果上述约束是你的特定用例的要求,你应该改用 Node.insertBefore(),或者使用 try...catch 来处理因此类情况引起的错误。
示例
moveBefore() 的基本用法
在此演示中,我们将展示 moveBefore() 的基本用法。
HTML
HTML 包含三个 <button> 元素和一个 <article> 元素。我们将使用这些按钮来控制将 DocumentFragment 实例插入到 <article> 中以及清空它。
<button id="insert1">Insert fragment</button>
<button id="insert2">Insert modified fragment</button>
<button id="clear">Clear</button>
<article id="wrapper"></article>
CSS
我们为之后将作为 JavaScript 生成的 DocumentFragment 子节点插入页面的元素提供了一些基本的样式,以增强其外观和间距。
#section1,
#section2,
#mover {
display: inline-block;
width: 200px;
height: 30px;
border: 5px solid rgb(0 0 0 / 0.25);
margin-top: 10px;
}
#section1,
#section2 {
background-color: hotpink;
}
#mover {
background-color: orange;
}
JavaScript
在我们的脚本中,我们定义了一个名为 createFragment() 的函数,该函数创建一个 DocumentFragment,其中包含一个 <div> 元素和两个 <section> 元素作为直接子节点。
然后,我们通过 addEventListener() 为每个 <button> 附加一个点击事件监听器。
- 第一个按钮将
DocumentFragment追加到#wrapper<article>元素中,不做任何修改。 - 第二个按钮将
DocumentFragment追加到#wrapper<article>元素中,但首先使用moveBefore()将<div>移动到DocumentFragment的第二个子节点位置,而不是第一个。 - 第三个按钮使用
innerHTML来清空#wrapper<article>元素。
const wrapper = document.getElementById("wrapper");
const insertBtn1 = document.getElementById("insert1");
const insertBtn2 = document.getElementById("insert2");
const clearBtn = document.getElementById("clear");
function createFragment() {
const fragment = new DocumentFragment();
const divElem = document.createElement("div");
const section1 = document.createElement("section");
const section2 = document.createElement("section");
divElem.id = "mover";
section1.id = "section1";
section2.id = "section2";
fragment.appendChild(divElem);
fragment.appendChild(section1);
fragment.appendChild(section2);
return fragment;
}
insertBtn1.addEventListener("click", () => {
const fragment = createFragment();
wrapper.appendChild(fragment);
});
insertBtn2.addEventListener("click", () => {
const fragment = createFragment();
fragment.moveBefore(
fragment.querySelector("#mover"),
fragment.querySelector("#section2"),
);
wrapper.appendChild(fragment);
});
clearBtn.addEventListener("click", () => {
wrapper.innerHTML = "";
});
结果
渲染后的示例如下所示:
尝试点击前两个按钮几次,注意第二个按钮如何修改 DocumentFragment 的结构。
规范
| 规范 |
|---|
| DOM # dom-parentnode-movebefore |
浏览器兼容性
加载中…