for循环调用appendChild仅插入隔项子元素的原因及修复方案
问题原因
parent.childNodes返回的是实时NodeList集合,会随DOM结构变化自动更新:当你调用wrap.append(children[i])时,对应元素会从原父节点的子节点列表中被移除,NodeList长度自动减1,后续所有元素会整体向前移动一位。- 子元素分行书写时,HTML的换行、缩进会生成文本节点填充在元素节点之间,循环时跳过文本节点的逻辑刚好抵消了实时集合前移带来的索引偏移,所以运行结果符合预期;子元素同行书写时没有多余文本节点,每次移动元素后索引错位,就会出现隔项子元素被跳过的问题。
修复方案
将实时集合转换为静态数组遍历,避免DOM变化带来的索引偏移,同时可以直接用parent.children获取所有元素子节点,省去节点类型判断步骤,修改后代码如下:
var container = document.getElementById("container"); const parentDivs = container.querySelectorAll(":scope *"); for (let parent of parentDivs) { // 创建包裹容器 let wrap = document.createElement('div'); wrap.id = 'wrap-of-' + parent.id; // 把实时的元素集合转为静态数组,遍历不受后续DOM操作影响 const children = Array.from(parent.children); for (let child of children) { child.setAttribute("data", "somedata"); wrap.append(child); } parent.appendChild(wrap); }
内容的提问来源于stack exchange,提问作者deki0
相关产品推荐
相关产品推荐

