JavaScript Toggle功能失效,求任务点击添加删除线的解决方案
问题分析
你当前代码的核心问题:
document.querySelectorAll(".task")返回的是NodeList集合,无法直接调用addEventListener,这是代码报错的直接原因。- 每次添加任务时都给所有任务重复绑定点击事件,会导致同一事件被触发多次。
- 删除按钮使用了重复的
id="deleteButton",querySelector只会选中第一个按钮,后续删除按钮无法绑定事件。
下面提供两种易理解的修复方案:
方案1:创建任务时直接绑定事件(直观易懂)
这种方式在每次生成新任务元素后,直接给单个任务绑定切换删除线的事件,同时给对应删除按钮绑定删除逻辑,避免重复绑定和ID冲突问题。
修改后的JavaScript代码:
const addBtn = document.querySelector("#push"); const taskInput = document.querySelector("#taskInput"); const taskOutput = document.querySelector("#tasks"); addBtn.addEventListener("click", function() { let newTasks = taskInput.value.trim(); if (!newTasks) { alert("Please enter a task"); return; } // 逐个创建DOM元素,避免innerHTML拼接的风险 const taskDiv = document.createElement('div'); taskDiv.className = 'task'; const taskSpan = document.createElement('span'); taskSpan.textContent = newTasks; const deleteBtn = document.createElement('button'); deleteBtn.className = 'delete'; deleteBtn.innerHTML = '<i class="fa-solid fa-trash"></i>'; // 绑定删除事件,阻止冒泡避免触发任务点击 deleteBtn.addEventListener('click', function(e) { e.stopPropagation(); taskDiv.remove(); }); // 绑定切换删除线事件 taskDiv.addEventListener('click', function() { this.classList.toggle('completed'); }); // 组装元素并添加到页面 taskDiv.appendChild(taskSpan); taskDiv.appendChild(deleteBtn); taskOutput.appendChild(taskDiv); // 清空输入框 taskInput.value = ''; });
方案2:事件委托(更高效,适合大量任务)
利用事件冒泡特性,只给父容器#tasks绑定一次事件,所有子元素的点击都由父容器统一处理,无需每次添加任务都绑定新事件,性能更优。
修改后的JavaScript代码:
const addBtn = document.querySelector("#push"); const taskInput = document.querySelector("#taskInput"); const taskOutput = document.querySelector("#tasks"); // 给父容器绑定一次事件委托 taskOutput.addEventListener('click', function(e) { const target = e.target; // 判断点击的是任务项(或任务内的文本) if (target.classList.contains('task') || target.parentElement.classList.contains('task')) { const taskDiv = target.classList.contains('task') ? target : target.parentElement; taskDiv.classList.toggle('completed'); } // 判断点击的是删除按钮(或按钮内的图标) if (target.classList.contains('delete') || target.parentElement.classList.contains('delete')) { const deleteBtn = target.classList.contains('delete') ? target : target.parentElement; deleteBtn.parentElement.remove(); } }); addBtn.addEventListener("click", function() { let newTasks = taskInput.value.trim(); if (!newTasks) { alert("Please enter a task"); return; } // 用innerHTML拼接任务(注意不要用重复ID) taskOutput.innerHTML += ` <div class="task"> <span>${newTasks}</span> <button class="delete"><i class="fa-solid fa-trash"></i></button> </div> `; taskInput.value = ''; });
内容的提问来源于stack exchange,提问作者oceanotrash
相关产品推荐
相关产品推荐

