addEventListener为其他函数创建的元素绑定点击事件失效问题求助
问题原因
Node.cloneNode()方法的深克隆仅会复制DOM节点的结构、属性以及内联事件(比如写在HTML里的onclick="xxx"),不会复制通过addEventListener绑定的事件监听器。你仅给初始化创建的模板删除按钮绑定了点击事件,后续克隆生成的所有删除按钮都没有绑定del回调,自然触发不了。- 额外的代码逻辑问题:输入非空判断逻辑存在漏洞、
del函数缺少闭合的右括号、删除按钮用了id属性,克隆后会出现重复id的不符合规范问题。
解决方法
推荐使用事件委托实现,不需要给每个新增的删除按钮单独绑定事件,直接给父级menu绑定事件即可,性能更高也更适配动态新增的节点:
let input = document.getElementById("input"); let menu = document.getElementById("menu"); let add = document.getElementById("addtask"); let task = document.createElement("div"); let deleteBtn = document.createElement("button"); let btnDetails = document.createTextNode("Delete"); let content = document.createElement("p") // 构建task模板 task.appendChild(content); task.appendChild(deleteBtn); deleteBtn.appendChild(btnDetails) task.classList.add("task"); deleteBtn.classList.add("delete-btn") // id改为class,避免重复id问题 // 直接给父级menu绑定事件委托 menu.addEventListener('click', function(e) { // 判断点击的是不是删除按钮 if (e.target.classList.contains('delete-btn')) { // 移除当前删除按钮所属的任务节点 e.target.closest('.task').remove() console.log("deleted") } }) add.onclick = function () { // 修正输入判断逻辑,排除空值、全空格的情况 if (input.value.trim() !== '') { content.innerText = input.value; let cloned = task.cloneNode(true); menu.appendChild(cloned) // 新增完成后清空输入框 input.value = '' } else { console.log("empty"); } };
如果不想用事件委托,也可以在克隆模板之后,给新生成的删除按钮单独绑定事件:
add.onclick = function () { if (input.value.trim() !== '') { content.innerText = input.value; let cloned = task.cloneNode(true); // 给克隆出来的删除按钮重新绑定事件 cloned.querySelector('.delete-btn').addEventListener('click', del) menu.appendChild(cloned) input.value = '' } else { console.log("empty"); } }; function del(e) { e.target.closest('.task').remove() console.log("deleted") }
内容的提问来源于stack exchange,提问作者MIAAD
相关产品推荐
相关产品推荐

