作者:@Bramus
原文:https://www.bram.us/2025/01/16/move-elements-around-the-dom-while-preserving-their-state-with-movebefore/
背景
Chrome 133 版本(将于 2 月 4 日发布稳定版)引入了一个新的 DOM 操作方法:Node.prototype.moveBefore
。这一方法虽然看似简单,但其意义重大,因为它能够在移动 DOM 元素时保留元素的状态。传统的 DOM 移动操作通常需要先移除元素再重新插入,这会导致元素的状态重置,而 moveBefore
则避免了这一问题。
【第3444期】Chrome 131 开发者工具的新变化
要点
1、保留元素状态
moveBefore
方法能够在移动 DOM 元素时保留其状态,这意味着:内嵌框架 (iframe) 会保持加载状态,活动元素会保持焦点,弹出窗口、全屏模式、模态对话框会保持打开状态,CSS 过渡和动画会继续执行。
moveBefore 可以用于各种需要移动 DOM 元素并保留其状态的场景,例如:
2、语法简洁
moveBefore
的语法与 insertBefore
类似,开发者可以轻松替换现有的代码。例子:
传统上,开发者使用 Node.prototype.insertBefore
方法来移动 DOM 元素。然而,使用 insertBefore 方法会导致被移动的节点重新加载并回到其初始状态。
例如,以下代码使用 insertBefore
方法移动一个 iframe 元素:
document.querySelector('#classic').addEventListener('click', () => {
const $newSibling = getRandomElementInBody();
const $iframe = document.querySelector('iframe');
document.body.removeChild($iframe);
document.body.insertBefore($iframe, $newSibling);
});
即使省略了 removeChild 的调用,insertBefore 方法也会自动移除目标节点,即使目标节点仍然连接到父节点。
与 insertBefore 不同,moveBefore 方法在移动元素时保留了元素的状态。以下代码使用 moveBefore 方法移动相同的 iframe 元素:
document.querySelector('#classic').addEventListener('click', () => {
const $newSibling = getRandomElementInBody();
const $iframe = document.querySelector('iframe');
document.body.moveBefore($iframe, $newSibling);
});
使用 moveBefore 方法,被移动的 iframe 元素会继续播放其内容,而不会重新加载。
使用以下代码检测浏览器是否支持 moveBefore:
if (!("moveBefore" in Element.prototype)) {
// 不支持 moveBefore
}
3、浏览器支持
目前,只有 Chrome 133 及更高版本支持 moveBefore。Safari 和 Firefox 也表示支持该 API,但尚未发布正式版本。
示例
document.querySelector('#movebefore').addEventListener('click', () => {
const $newSibling = getRandomElementInBody();
const $iframe = document.querySelector('iframe');
document.body.moveBefore($iframe, $newSibling);
});
Demo:https://codepen.io/bramus/full/xbKzPJB
分析
传统的 DOM 移动操作通常通过 removeChild
和 insertBefore
实现,这种方式会导致元素的状态重置。例如,移动一个 iframe 时,iframe 会重新加载,导致用户体验中断。而 moveBefore
方法则解决了这一问题,使得在移动元素时,iframe 可以继续播放,焦点元素保持焦点,CSS 动画和过渡也不会中断。
从技术角度来看,moveBefore
的实现并不复杂,但其对开发者体验和用户体验的提升是显著的。尤其是在现代 Web 应用中,动态 DOM 操作非常常见,保留元素状态的能力将大大减少不必要的重新渲染和状态恢复操作。
影响
1、开发者体验提升
开发者不再需要手动处理元素状态的保存和恢复,减少了代码复杂性和潜在的错误。
2、用户体验优化
用户在使用 Web 应用时,不会因为 DOM 操作而中断当前的操作或体验,例如视频播放、模态对话框的保持等。
3、浏览器兼容性
虽然目前仅 Chrome 支持,但 Safari 和 Firefox 已表示支持,未来该 API 有望成为 Web 标准的一部分。
结论
Node.prototype.moveBefore
的引入是 Web 开发中的一项重要进步,它不仅简化了开发者的工作流程,还提升了用户体验。随着更多浏览器的支持,这一 API 有望成为 Web 开发中的标配工具。未来,我们可以期待更多类似的 API 出现,进一步优化 Web 应用的性能和用户体验。
😀 每天只需花五分钟即可阅读到的技术资讯,加入【早阅】共学,可联系 vx:zhgb_f2er
5 分钟新知:了解技术资讯的一种方式。
🚀可直接通过阅读原文了解详细内容。