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

如何从div子元素获取其他子元素并同步删除tasks数组任务?

解决方案

核心问题修复与优化

1. 正确获取父元素内的子元素

你之前用document.querySelector(${btn.parentElement} .content)出错,是因为把DOM元素直接塞进模板字符串时,它会被转成[object HTMLLIElement]这种无效选择器。直接调用父元素的querySelector方法就能解决:

let p = btn.parentElement.querySelector('.content');

2. 解决重名任务误删:给任务加唯一ID

给每个任务生成唯一ID,删除时通过ID匹配,彻底避免名称重复导致的误删。修改Task构造函数并在渲染时把ID存在元素属性里:

// 修改Task构造函数,添加唯一ID
function Task(task) {
    this.id = Date.now() + Math.random(); // 用时间戳+随机数生成唯一标识
    this.task = task;
    this.done = false;
}

// 渲染列表项时,把ID存在li的自定义属性中
tasksHTML.insertAdjacentHTML(
    "beforeend",
    `
        <li class="task" data-task-id="${task.id}">
            <div class="left">
                <input type="checkbox" class="box" />
                <p class="content">${task.task}</p>
            </div>
            <button class="btn delete">
                <i class="fa-solid fa-trash-can"></i>
            </button>
        </li>
    `,
);

3. 优化事件绑定:避免重复绑定+用事件委托更高效

你原来每次提交表单都重新绑定所有删除按钮,会导致同一个按钮被多次绑定,点击一次触发多次回调。直接用事件委托,在父元素上绑定一次就够:

// 移除原来的deleteBtn函数,换成这个事件委托
tasksHTML.addEventListener('click', (e) => {
    // 判断点击的是删除按钮或内部图标
    const deleteBtn = e.target.closest('.delete');
    if (!deleteBtn) return;
    
    const li = deleteBtn.closest('.task');
    const taskId = parseFloat(li.dataset.taskId);
    
    // 移除页面上的列表项(彻底删除而非隐藏)
    li.remove();
    
    // 从数组中删除对应任务
    tasks = tasks.filter(task => task.id !== taskId);
    
    // 判断是否需要移除背景
    if (tasks.length === 0) {
        tasksHTML.classList.remove("background");
        oneTask = false;
    }
});

修改后的完整代码

var tasks = [];
var oneTask = false;

// html elements
const form = document.querySelector("form");
const formInput = document.querySelector(".task-input");
const tasksHTML = document.querySelector(".tasks");

// objects
function Task(task) {
    this.id = Date.now() + Math.random(); // 生成唯一ID
    this.task = task;
    this.done = false;
}

// 事件委托处理删除逻辑
tasksHTML.addEventListener('click', (e) => {
    const deleteBtn = e.target.closest('.delete');
    if (!deleteBtn) return;
    
    const li = deleteBtn.closest('.task');
    const taskId = parseFloat(li.dataset.taskId);
    
    li.remove();
    tasks = tasks.filter(task => task.id !== taskId);
    
    if (tasks.length === 0) {
        tasksHTML.classList.remove("background");
        oneTask = false;
    }
});

// 表单提交事件
form.addEventListener("submit", (e) => {
    e.preventDefault(); // 阻止页面刷新
    if (!formInput.value.trim()) return; // 不允许添加空任务
    
    const newTask = new Task(formInput.value);
    tasks.push(newTask);
    formInput.value = "";
    addItem(newTask);
    
    if (!oneTask) {
        oneTask = true;
        tasksHTML.classList.add("background");
    }
});

// 添加列表项函数
function addItem(task) {
    tasksHTML.insertAdjacentHTML(
        "beforeend",
        `
            <li class="task" data-task-id="${task.id}">
                <div class="left">
                    <input type="checkbox" class="box" />
                    <p class="content">${task.task}</p>
                </div>
                <button class="btn delete">
                    <i class="fa-solid fa-trash-can"></i>
                </button>
            </li>
        `,
    );
}

额外优化说明

  • 加了e.preventDefault()阻止表单默认提交,避免页面刷新
  • 新增空任务判断,防止添加空白内容
  • 用tasks.push()代替tasks[tasks.length] = ...,更符合数组操作规范
  • 用li.remove()彻底删除DOM元素,而非隐藏

内容的提问来源于stack exchange,提问作者tices

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 22:06:33