2.事件委托:更高效的监听
来源:https://w0hog67yl81.feishu.cn/wiki/NT2dwqrRyivoqBkAZwAcVmKjnXb
采集状态:已完成正文采集;每次约0.55屏连续滚动到文末,按block id和代码行号累积;代码行号连续。
1. 核心原理:事件冒泡 (Event Bubbling)
当你点击一个按钮时,你不仅仅是点击了那个按钮。在浏览器看来,你同时还点击了按钮所在的容器、整个页面、甚至 window。
事件冒泡 指的是,当一个元素上的事件被触发时,该事件会从这个元素开始,逐级向上层父元素传播,直到 document 对象。
•
比喻: 就像往水里扔一块石头(触发事件的元素),涟漪(事件)会从中心点不断向外扩散(向父元素传播)。
2. 什么是事件委托?
基于事件冒泡的原理,我们不必为每个子元素都绑定事件监听器,而是只在它们的**父元素**上绑定一个监听器。这个父元素就像一个“受委托”的代表,统一处理所有子元素上冒泡过来的事件。
场景对比
假设我们有一个商品列表
,里面有很多 - 项,我们想在点击每个
- 时获取其内容。
•
常规做法 (不推荐):
const items = document.querySelectorAll('ul li');
items.forEach(item => {
item.addEventListener('click', () => {
console.log('你点击了:', item.textContent);
});
});
◦
缺点:
i.
性能开销大: 如果有 1000 个
- ,就需要创建 1000 个事件监听器,占用大量内存。
ii.
维护困难: 如果通过 JS 动态添加了一个新的
- ,你需要手动为这个新元素再次绑定事件。
•
事件委托 (推荐):
const list = document.querySelector('ul');
list.addEventListener('click', (event) => {
// 只有当被点击的确实是 li 元素时才响应
if (event.target.tagName === 'LI') {
console.log('你点击了:', event.target.textContent);
}
});
◦
优点:
i.
性能好: 无论有多少子元素,都只需要在父元素上绑定**一个**监听器。
ii.
维护方便: 动态添加的子元素也能被监听到,因为事件会自然冒泡到父元素,而父元素的监听器一直都在。
3. event.target vs event.currentTarget:关键区别
在处理委托事件时,正确区分 event.target 和 event.currentTarget至关重要。
属性
描述
在委托场景中
比喻
event.target
事件的真正来源。它是用户实际点击的那个最具体的元素。
可能是
- ,也可能是
- 里的 或
。
包裹的目标:快递员要去送一个包裹,target 就是包裹上写的具体门牌号,例如“302室”。
event.currentTarget
监听器所在的元素。也就是你调用 addEventListener 的那个元素。
永远是父元素 。
送达的大楼:快递员把车停在哪栋大楼下,这栋大楼就是 currentTarget,例如“幸福小区A栋”。
总结: 在事件委托的回调函数中,我们通常关心的是 event.target,因为它告诉我们是哪个子元素触发了事件。而 event.currentTarget 则始终是那个我们绑定事件的父元素。