共计 1793 个字符,预计需要花费 5 分钟才能阅读完成。
核心概念:三个参数拆解
- type(事件类型)
字符串类型,表示监听的事件名称(如'click'、'scroll')。注意: - 不要加
on前缀(错误示例:'onclick') -
大小写敏感(
'keydown'≠'KeyDown')
-
listener(回调函数)
事件触发时执行的函数,可通过event参数获取事件对象。关键细节: - 避免使用匿名函数(不利于移除监听)
-
箭头函数会改变
this指向 -
options/useCapture(控制参数)
第三参数有两种形式: - 布尔值:控制捕获 / 冒泡阶段(默认
false即冒泡阶段) - 对象:支持更精细配置(如
{passive: true})
痛点分析:那些年我们踩过的坑
-
内存泄漏:未移除的事件监听导致 DOM 元素无法回收
// 错误案例 element.addEventListener('click', () => {console.log('点击后回调依旧存在内存中'); }); -
意外的事件冒泡:子元素触发事件影响父元素
<div id="parent"> <button id="child"> 点击我触发父元素事件 </button> </div> -
滚动卡顿 :未使用
passive优化的滚动事件阻塞主线程
技术方案:useCapture vs options 对象
1. 捕获与冒泡阶段控制
// 捕获阶段触发(父→子)document.addEventListener('click', handler, true);
// 冒泡阶段触发(子→父,默认)document.addEventListener('click', handler, false);
2. options 对象高级配置
// 最佳实践组合
element.addEventListener('scroll', handler, {passive: true, // 告诉浏览器不会调用 preventDefault()
once: true, // 只触发一次后自动移除
capture: false // 冒泡阶段
});
代码实验室:完整示例
// 事件委托示例(利用冒泡)document.getElementById('list').addEventListener('click', (event) => {if (event.target.tagName === 'LI') {console.log('点击的列表项 ID:', event.target.id);
}
}, {capture: false});
// 性能敏感场景
window.addEventListener('touchmove', (e) => {// 此处不会调用 e.preventDefault()
}, {passive: true}); // 提升滚动流畅度
// 一次性事件
const modal = document.querySelector('.modal');
modal.addEventListener('animationend', () => {modal.remove();
}, {once: true});
性能考量:实测数据对比
使用 Chrome DevTools 的 Performance 面板测试:
| 参数配置 | 滚动事件处理耗时 |
|---|---|
无passive |
120ms |
{passive: true} |
8ms |
{capture: true} |
无明显差异 |
避坑指南:5 个高频错误
-
匿名函数无法移除
解决方案:始终使用具名函数引用 -
误用 stopPropagation
替代方案:使用event.target精细控制 -
重复添加相同监听器
检测方法:getEventListeners(element)(Chrome 控制台) -
未考虑移动端触摸事件
必加配置:{passive: true} -
SSR hydration 报错
修复方案:添加事件前检查 DOM 是否存在
优化思路:项目实践建议
- 事件委托:在父级监听子元素事件(适合动态内容)
- 懒加载监听:IntersectionObserver 替代 scroll 事件
- 性能监控 :用
Event Timing API分析事件处理耗时 - 清理策略:
// 组件卸载时 const cleanUp = () => {element.removeEventListener('click', handler); }; // React 示例 useEffect(() => cleanUp, []);
最后思考:你当前项目中有多少事件监听器可以通过
once或passive优化?试试在控制台运行getEventListeners(window)自查吧!
正文完
发表至: 前端开发
近一天内

