使用JavaScript insertBefore()向h1前插入元素时页面无限加载如何解决
问题根因
- 你定义的
var cn=document.body.children获取的是 实时HTMLCollection集合,它会随DOM结构的变化自动更新,不是固定的DOM快照。 - 当循环遍历到索引为
i的<h1>标签时,你执行document.body.insertBefore(p,cn[i]),会在<h1>前面插入一个新的<p>标签:- 此时
cn的长度自动+1 - 原位置
i的<h1>会被挤到索引i+1的位置
- 此时
- 下一次循环
i自增1,刚好又指向了被挤到i+1位置的<h1>标签,触发重复插入逻辑,最终陷入无限循环,导致页面卡死。 - 其他插入逻辑不会触发问题的原因:给DIV内部插入子元素、修改UL的子节点内容,都不会修改
document.body.children的元素顺序和长度,不会影响遍历逻辑。 - 额外冗余代码:你代码中
else分支的document.write()没有实际作用,若页面加载完成后调用该方法会清空整个文档内容,建议直接删除。
修复方案
最简单的修复方式是把实时集合转为静态数组,遍历固定的DOM快照,避免DOM修改影响遍历逻辑:
将代码中的
var cn=document.body.children;
修改为:
// 转成静态数组,不受后续DOM修改影响 var cn = Array.from(document.body.children);
如果不想转数组,也可以用倒序遍历的方式实现:
var cn=document.body.children; // 从最后一个元素往前遍历,插入新元素不会影响未遍历的元素索引 for(var i = cn.length - 1; i >= 0; i--){ // 原有逻辑保持不变 }
内容的提问来源于stack exchange,提问作者Shahbaz Shaik
相关产品推荐
相关产品推荐

