You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何统计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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 14:15:42