如何从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
相关产品推荐
相关产品推荐

