网站首页 > 开源技术 正文
1. 传统 DOM 操作丢失元素状态
自 1998 年推出第一个 DOM 标准草案以来,文档对象模型(DOM)就只有移除和插入原语。因此,每当开发者将 DOM 中的某个元素从一个地方 “移动” 到另一个地方时,实际上是在后台进行移除和插入操作。例如,典型的 appendChild() 或 insertBefore() API 都是先从旧父元素中移除元素,然后再将其重新插入到新元素。
因此,所谓的 “移动” 操作实际上是在 “移除和插入”,而这通常不会影响用户体验。例如,在 DOM 中 “移动”
时,这两个操作不会产生任何破坏性副作用,但在移动保存重要状态的复杂节点,例如:
2.Chrome 133 支持新的 moveBefore() API
Chrome 133 中推出了新的 moveBefore() DOM API,允许开发者更轻松地在 DOM 中移动元素而不会丢失状态。
Introduces a state-preserving atomic move primitive to the DOM, by calling Node.moveBefore. See https://github.com/whatwg/dom/issues/1255. – Mac, Windows, Linux, ChromeOS, Android
moveBefore() 采用与 insertBefore() 相同的参数,该 API 以原子方式将目标节点移动到新父节点而不重置元素状态,从而允许开发人员能够使用可移动动画 (movable animations)、iframe、全屏元素等构建动态体验。
chrome://flags/#atomic-move
moveBefore() 功能可用于 ParentNode,如 Element、Document、DocumentFragment。其会移动而非移除 / 插入元素,同时保留以下状态:
- iframes 保持加载状态
- 活动 (active) 元素保持焦点
- 弹出窗口、全屏、模式对话框保持打开
- CSS 过渡和动画继续
3.React 支持最新的 moveBefore() API
React 在最新的一个 PR([Fiber] Support moveBefore at the top level of a container #32036)中已经宣布支持 moveBefore 方法,其被用于在保留元素状态的情况下重新对根元素排序。
下面是 React 源码中对 insertInContainerBefore 中的重新实现,其也用到的 moveBefore 方法,同时添加了很多兼容代码:
引入 moveBefore 方法后,对 React 源码中部分文件的体积也产生了一定的影响,但变化不明显,如下图:
参考资料
https://developer.chrome.com/blog/movebefore-api
https://chromestatus.com/feature/5135990159835136
https://github.com/sebmarkbage/react/blob/refs/heads/movebefore/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js
https://x.com/htmx_org/status/1887329202573353431
猜你喜欢
- 2025-03-13 JavaScript对比TypeScript(JavaScript对比两个json)
- 2025-03-13 在 JavaScript 中替换所有指定字符 3 种方法
- 2025-03-13 深入理解 ArkUI - 页面更新原理(页面实时更新数据)
- 2025-03-13 [西门子PLC]S7-1200调试翻车实录:沿触发MOV指令的重要性
- 2025-03-13 当下弹幕互动游戏源码开发教程及功能逻辑分析
- 2025-03-13 htmx 会是新的 jQuery?(html htm)
- 2025-03-13 事件——《JS高级程序设计》(js 高级程序设计)
- 2025-03-13 干货教程 | 用TFLi 和SPICE模型打造听歌识谱App
- 2025-03-13 [汇川PLC] 汇川IFA程序框架07-配置EtherCat伺服和伺服功能块
- 2025-03-13 如何写出优雅的 JS 代码,变量和函数的正确写法
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- jdk (81)
- putty (66)
- rufus (78)
- 内网穿透 (89)
- okhttp (70)
- powertoys (74)
- windowsterminal (81)
- netcat (65)
- ghostscript (65)
- veracrypt (65)
- asp.netcore (70)
- wrk (67)
- aspose.words (80)
- itk (80)
- ajaxfileupload.js (66)
- sqlhelper (67)
- express.js (67)
- phpmailer (67)
- xjar (70)
- redisclient (78)
- wakeonlan (66)
- tinygo (85)
- startbbs (72)
- webftp (82)
- vsvim (79)
本文暂时没有评论,来添加一个吧(●'◡'●)