如何移除元素的所有子节点?JS开发ToDo应用清空按钮删项异常如何修复
问题根因
childNodes返回的是实时动态NodeList,当你调用removeChild删除元素时,该集合会实时更新、长度自动收缩。forEach遍历是按初始索引依次执行的,删除索引0的元素后,原索引1的元素会前移到索引0位置,下一次遍历直接访问索引1,就会跳过该元素,最终表现为隔项删除。
修复方案
以下为3种常用修复方案,可根据场景选择:
- 方案1:直接清空innerHTML(实现最简单,适合ul下没有需要保留的其他子元素的场景)
function clearAll(e){ e.preventDefault() todoList.innerHTML = '' }
- 方案2:将实时NodeList转为静态数组后遍历(遍历对象固定,不受删除操作影响,逻辑更可控)
function clearAll(e){ e.preventDefault() // 转成静态数组,遍历过程不会受元素删除影响 const allItems = Array.from(todoList.childNodes) allItems.forEach(function(item){ todoList.removeChild(item) }) }
也可以用展开运算符实现转换:const allItems = [...todoList.childNodes]
- 方案3:倒序遍历实时NodeList(从最后一个元素开始删除,删除操作不会影响未遍历的元素索引)
function clearAll(e){ e.preventDefault() const allItems = todoList.childNodes // 从最后一位往前遍历 for(let i = allItems.length - 1; i >= 0; i--){ todoList.removeChild(allItems[i]) } }
补充说明:如果todoList下除了动态添加的任务项,还有其他需要保留的固定子元素,只需要在遍历逻辑中添加筛选条件,比如判断item的类名是否为任务项专属类名,再执行删除即可。
内容的提问来源于stack exchange,提问作者Shreeja Geeda
相关产品推荐
相关产品推荐

