为何使用prepend移动元素后会丢失滚动位置?
问题分析与解答
问题场景
给定如下HTML结构:
<div id="parent"> <div>...</div> <div>...</div> <div>...</div> <div>...</div> </div>
其中parent的子元素具备可滚动特性。
执行以下操作后出现滚动位置丢失的问题:
- 滚动子元素后,从
parent中取出目标元素:
const child = parent.children[3];
此时该元素的滚动位置正常:
child.scrollTop; // 示例值:269px
- 将该元素添加回
parent的开头:
parent.prepend(child);
此时元素的滚动位置被重置:
child.scrollTop; // 0px
核心问题
为何移动元素位置后,其滚动位置会丢失?
原因解释
当你通过prepend移动DOM元素时,浏览器的操作逻辑是先将元素从原位置移除,再插入到新位置。在元素脱离文档流(被移除)的阶段,浏览器会默认重置该元素的滚动状态:
- 浏览器认为不在文档中的元素无需维护滚动位置,会释放相关的滚动状态资源以优化性能。
- 当元素被重新插入到DOM中时,会以默认的初始状态渲染,其中就包括
scrollTop: 0。
如果需要保留滚动位置,可在移除元素前手动保存scrollTop的值,插入完成后再将值恢复给元素:
// 保存滚动位置 const savedScrollTop = child.scrollTop; // 移动元素 parent.prepend(child); // 恢复滚动位置 child.scrollTop = savedScrollTop;
内容的提问来源于stack exchange,提问作者Strazan
相关产品推荐
相关产品推荐

