document与元素调用addEventListener的区别、性能及选型疑问
document.addEventListener() 与元素调用addEventListener()的区别及性能分析
核心区别
- 监听目标不同:
- 元素调用
addEventListener():直接给具体DOM元素绑定事件,只有该元素触发对应事件时才会执行回调。 document.addEventListener():给整个文档的根节点绑定事件,事件需经过冒泡/捕获阶段传播到document时才会触发(除非事件传播被主动阻止)。
- 元素调用
- 触发范围不同:
- 元素绑定的事件仅对目标元素生效;
document绑定的事件会响应整个文档内所有符合条件的事件(比如绑定click后,页面任意元素的点击事件冒泡到document时都会触发回调)。
- 元素绑定的事件仅对目标元素生效;
- 执行时机不同:
- 元素绑定的事件在事件流的目标阶段(或指定的捕获/冒泡阶段)执行;
document绑定的事件则在冒泡阶段的最末尾(或捕获阶段的最开始)执行。
- 元素绑定的事件在事件流的目标阶段(或指定的捕获/冒泡阶段)执行;
性能差异
- 直接给元素绑定事件的性能更优:事件触发时无需经过额外的传播路径,直接在目标元素上执行回调;而
document绑定的事件需要等待事件从触发元素逐层传播到根节点,多了传播环节。这种差异在普通点击等低频事件中几乎可以忽略,但在mousemove、scroll这类高频事件中会更明显。 - 特殊场景下
document绑定更省内存:如果需要给大量同类元素绑定相同事件(比如列表所有项的点击),使用document做事件委托(只绑定一次事件,通过event.target判断触发元素)会比给每个元素单独绑定更节省内存,但这和你当前单元素绑定的场景无关。
示例代码的优劣对比
你的两个示例都是给具体按钮元素绑定click事件,核心区别是DOM元素的获取方式,选项1更优、更规范,原因如下:
- 减少DOM查询开销:
document.getElementById()是DOM查询操作,选项1在构造函数中仅查询一次按钮元素并将引用存在实例属性this.my_button中,后续复用该元素(比如修改样式、绑定其他事件)无需重复查询,性能更好。 - 提升代码可维护性:
若后续需要修改按钮的选择器,只需在构造函数中修改一次getElementById的参数即可,不用在多个方法中逐一修改。 - 避免潜在的引用问题:
若events()方法被多次调用(虽然当前示例中只调用一次),选项2会重复执行DOM查询,而选项1直接复用已保存的元素引用,逻辑更稳定。
内容的提问来源于stack exchange,提问作者kal3js
相关产品推荐
相关产品推荐

