以下代码,通过遍历删除子节点会有问题
const userList = document.getElementById('userList');
for (let i = 0; i < userList.children.length; i++) {
const element = userList.children[i];
element.remove();// userList.removeChild(element);
}
看起来很符合直觉。
事实上,
调用element.remove() 或parentNode.removeChild(element) 删除该元素会改变原数组(上面的userList数组,类型为HTMLCollection,是个可迭代对象)
类似循环用Array.splice删除数组元素一样。
这导致子元素删除不全。(因为userList.children.length 每循环一次就减小)。
那么删除所有子元素时,每次遍历出HTMLCollection 对象的第一个值删除即可。
代码
let ele;
while ((ele = userList.children.item(0))) {
ele.remove();
}
// or
while ((ele = userList.firstChild)) { // userList.lastChild
ele.remove();
}
这里使用HTMLCollection.item() 来获取第1个元素。也可以用数组方式获取。element.children[0]
既然获取第一个元素,有更简单的方式 element.firstChild。同理最后一个元素element.lastChild (这也是网上很多方案的代码所使用的)
firstChild / lastChild 返回的是Node类型,使用firstElementChild 、lastElementChild 来返回Element 类型。
至于Node 和Element 区别么,请自行搜索。
PS
这就是我们当代前端过多依赖前端框架操作dom,而出现的原生js知识漏洞。