如何统计Todo列表未完成项数量并传入HTML渲染?
问题原因
你当前写的itemsLeft()函数没有实现计数逻辑,仅做了已完成项的隐藏操作,也没有把统计结果写入你预先选中的#leftDOM节点,同时计数逻辑没有和待办状态变更的动作绑定,所以无法正确展示未完成项数量。
修复方案
- 拆分职责:单独写计数渲染函数,只做未完成项遍历计数、结果渲染的逻辑,不要混入DOM显示/隐藏的筛选逻辑
- 实时触发:在所有会改变待办状态/数量的操作(标记完成/取消完成、清除已完成项、新增待办、筛选切换)完成后,自动调用计数函数更新展示值,不需要用户手动点击触发计数
- 修正遍历逻辑:用
children替代childNodes获取待办列表,避免遍历到标签间的换行文本节点导致脚本报错
修正后代码
把原有对应逻辑替换为以下代码即可:
//FILTERS AND COMPLETED ITEMS SECTION const itemsLeftInnerHTML = container.querySelector("#left"); const filterOptions = container.querySelectorAll(".item--filter"); const clearButton = container.querySelector(".filter__completed--clear"); // 核心:未完成项计数+渲染函数 const updateItemsLeftCount = () => { const todoItems = listContainer.children; let unFinishedCount = 0; for (const item of todoItems) { const todoTextNode = item.children[0].children[1]; if (!todoTextNode.classList.contains("completed")) { unFinishedCount++; } } itemsLeftInnerHTML.textContent = unFinishedCount; } // 标记完成/取消完成 function completedItem(event) { event.nextElementSibling.classList.toggle("completed"); messageAlert("Item Completed", "success"); updateItemsLeftCount(); // 状态变更后更新计数 } // 筛选逻辑 function filterItems(event) { const items = listContainer.children; const filterType = event.target.innerHTML.trim(); // 去除文本前后空格避免匹配失败 items.forEach((item)=> { const isCompleted = item.children[0].children[1].classList.contains("completed"); switch(filterType) { case "All": item.style.display = "flex"; break; case "Completed": item.style.display = isCompleted ? "flex" : "none"; break; case "Active": item.style.display = !isCompleted ? "flex" : "none"; break; } }) updateItemsLeftCount(); // 筛选后更新计数 } filterOptions.forEach((filterOption)=> { filterOption.addEventListener("click", filterItems); }) // 清除已完成项 const clearItems = ()=>{ const items = Array.from(listContainer.children); items.forEach((item)=> { if(item.children[0].children[1].classList.contains("completed")) { item.remove(); // 原逻辑仅隐藏,改为真实移除DOM节点符合常规交互 } }) updateItemsLeftCount(); // 清除后更新计数 } clearButton.addEventListener("click", clearItems); // 页面初始化时计算一次初始数量 updateItemsLeftCount(); // 注意:如果你有新增待办项的逻辑,在新增节点插入列表后,也需要调用一次updateItemsLeftCount()保证计数准确
补充说明
- 原代码中给
itemsLeftButton绑定itemsLeft的逻辑属于职责混淆:剩余未完成数量是全局实时展示的状态,不需要点击按钮触发计算。如果该按钮的作用是切换到「未完成项」筛选视图,直接给它绑定和其他筛选项一致的点击回调即可。 - 原
All筛选分支里判断clearButton.clicked的逻辑没有实际作用,clearButton是DOM节点,不存在自带的clicked属性,直接删除即可。
内容的提问来源于stack exchange,提问作者coding beast
相关产品推荐
相关产品推荐

