标准答案
- event.target 表示事件最初发生的目标节点,可能是按钮里的图标、文字节点或更深层的子元素。
- event.currentTarget 表示当前正在执行监听器的绑定节点。监听器绑在哪个元素上,执行这个监听器时 currentTarget 就是谁。
- 事件代理通常把监听器绑在父容器上。子元素触发事件后冒泡到父容器,currentTarget 是父容器,target 是实际触发事件的子节点。
- 代理逻辑通常用 target.closest 或 matches 找到符合条件的子项,再用 container.contains 做边界校验。这样可以统一处理已有子项和动态新增子项。
题目解析
事件代理依赖事件冒泡。不是所有事件都适合代理,例如 focus/blur 默认不冒泡,可以考虑 focusin/focusout 或捕获阶段。
target 不一定是你业务上想处理的元素。按钮里有 svg、span 或图标时,target 可能落在内部节点上,所以通常用 closest 找到带业务标记的元素。
代理时要校验目标仍在当前容器内。嵌套列表或多个容器共享选择器时,只靠 closest 可能误处理其它区域的元素。
代码示例
下面示例把监听器绑定在列表容器上,通过 target.closest 找到真实操作按钮。
JavaScript
const list = document.querySelector('#todo-list')
list.addEventListener('click', (event) => {
const button = event.target.closest('[data-action="remove"]')
if (!button || !list.contains(button)) {
return
}
console.log(event.currentTarget === list) // true
console.log(event.target) // 实际点击到的内部节点
button.closest('li')?.remove()
})常见误区
- 把 target 和 currentTarget 当成同一个元素。
- 事件代理时不检查目标是否属于当前容器。
- 点击嵌套元素时直接读取 target.dataset,导致读不到期望字段。