target、currentTarget 与 composedPath
本节用父级委托监听器区分 target、currentTarget 和事件路径;Shadow DOM 的重定向另行验证。
html
<div id="panel"><button id="save"><span>保存</span></button></div>
<script>
const panel = document.querySelector('#panel')
panel.addEventListener('click', (event) => {
console.log(event.target.id || event.target.tagName, event.currentTarget.id, event.composedPath().map(node => node.id || node.tagName))
})
</script>点击文字后观察 target 可能是 SPAN,而 currentTarget 始终是 panel。
规则与边界
- 平台保证、浏览器实现和业务约定必须分开;一个浏览器中的结果不能自动推广到所有宿主。
- 每个监听器、请求、观察器、缓存和焦点操作都要有清理/取消责任;页面或组件离开后不能继续写状态。
- 用户输入、URL、HTML、消息和持久化数据按不同信任边界处理;类型正确不代表内容可信。
- 失败、取消、超时、权限拒绝、配额不足和不支持要有不同的可观察结果。
机制拆解
target 是最初触发事件的节点,currentTarget 是当前正在执行监听器的节点;委托监听器中二者经常不同。Shadow DOM 或跨文档场景还要用 composedPath() 判断事件经过的真实路径。
可运行实验
html
<div id="panel"><button id="save">保存</button></div>
<script>
panel.addEventListener('click', event => {
console.log(event.target.id, event.currentTarget.id, event.composedPath().map(node => node.id || node.nodeName))
})
</script>点击按钮后应看到 save panel;把按钮内部加入 <span> 再点击文字,观察 target 变成 span,而 currentTarget 仍为 panel。
练习
- 点击按钮文字,记录
target、currentTarget和composedPath()的最后三项。 - 把按钮放入 ShadowRoot,比较开放和封闭模式下的 target 重定向。
- 说明事件委托何时应改为直接监听,特别是跨 Shadow DOM 边界时。 查看本节答案
下一步
完成答案核对后继续本章下一篇,并把实验日志保存在自己的项目中。