
本文详解在事件委托场景下为何 event.currentTarget.parentNode.remove() 失效,并提供基于 event.target.closest() 的可靠解决方案,适用于动态生成的 DOM 元素删除操作。
本文详解在事件委托场景下为何 `event.currenttarget.parentnode.remove()` 失效,并提供基于 `event.target.closest()` 的可靠解决方案,适用于动态生成的 dom 元素删除操作。
在使用原生 JavaScript 实现类似 jQuery 的事件委托时,一个常见误区是混淆 event.target 与 event.currentTarget。你当前的代码中:
if (event.target.classList.contains('delete')) {
event.currentTarget.parentNode.remove(); // ❌ 错误!
}此处 event.currentTarget 指向的是 document(因为你是在 document.addEventListener() 上绑定的监听器),而非被点击的 .delete 元素。因此 event.currentTarget.parentNode 实际是 document.parentNode(即 null),调用 .remove() 必然报错或静默失败。
更关键的问题在于:.target 是实际触发事件的最深子元素(例如 <i></i> 图标),而 .delete 很可能是其父级 <a></a> 标签。所以 event.target.classList.contains('delete') 在点击图标时会返回 false,导致条件不成立——事件根本不会进入删除逻辑。
✅ 正确做法是使用 event.target.closest('.delete'):
document.addEventListener('click', function(event) {
if (event.target.id === 'add') {
count++;
addAward(count);
}
// ✅ 安全获取最近的 .delete 祖先(含自身)
const deleteBtn = event.target.closest('.delete');
if (deleteBtn) {
// ✅ 删除其直接父容器(即包含 input 和按钮的 .col-lg-4)
deleteBtn.parentElement.remove();
}
});Element.closest(selector) 会从 event.target 开始向上遍历 DOM 树,返回第一个匹配选择器的祖先元素(包括自身)。它天然兼容嵌套结构(如 <a class="delete"><i class="fa-times"></i></a>),且语义清晰、浏览器兼容性好(IE 不支持,但现代项目可忽略)。
? 补充建议:
- 避免在
document级别过度监听全局点击事件,可缩小委托范围(如委托到#showAward)提升性能; - 删除前可增加确认逻辑(如
if (!confirm('确定删除?')) return;); - 若需清理关联资源(如已选文件、内存引用),应在
.remove()前手动处理。
最终修正后的完整逻辑简洁健壮,完美替代 jQuery 的 $(this).closest('.col-lg-4').remove(),是现代原生 JS 事件委托的标准实践。

















