本文深入解析JavaScript中的事件监听与事件委托机制。通过对比大量DOM元素绑定事件的两种方案,展示了利用事件冒泡进行委托的性能优势。文章包含构建测试环境的代码、性能测试数据及不同浏览器下的耗时分析,为高交互场景下的性能优化提供实用参考。
JavaScript事件监听与事件委托概述
本文通过具体实例详细解析JavaScript中的事件监听与事件委托技术,旨在为开发者提供实用的参考与借鉴。
事件监听与事件委托
在JavaScript开发中,element.addEventListener()是处理事件监听的常用方法。然而,当页面中存在大量需要绑定事件的元素时,直接为每个元素单独绑定监听器可能会引发性能瓶颈。此时,采用事件委托机制来统一处理事件监听,成为更优的解决方案。
事件传播的三个阶段与冒泡原理
每个事件在传播过程中都经历三个阶段
- 捕获阶段
- 到达目标阶段
- 冒泡阶段
事件委托的核心原理依赖于事件的冒泡机制。所谓冒泡,是指当事件发生时,事件会沿着DOM树结构从目标元素逐级向上传递,被各层级的父节点依次接收。
参考如下页面结构示例
<body>
<div id="div1">
<div id="div2">
<button>按钮</button>
</div>
</div>
</body>
当用户点击按钮时,事件首先由button元素接收,随后向上冒泡,依次被id="div1"、id="div2"接收,最终一直传递至document顶层。
基于这一特性,我们只需在父级元素上添加一个事件处理器,即可由其统一接收所有子节点的事件信息,这便是事件委托的实现方式。
事件监听与事件委托的性能对比实验
事件监听与事件委托性能比较
为了直观对比两种方式的性能差异,我们通过构建多个button元素并分别绑定事件监听器来进行测试。
第一步:构建若干个button元素,并添加到body中
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body id='body'>
<script type="text/javascript">
var body = document.getElementById('body');
var fragment = document.createDocumentFragment();
for (var i = 0; i < 100; i++) {
var btn = document.createElement('button');
btn.id = i;
btn.className = 'btn';
btn.type = 'button';
btn.innerText = '按钮'
fragment.appendChild(btn);
}
body.appendChild(fragment);
</script>
</body>
</html>
此时页面生成了100个按钮,id为0到99,class为'btn';fragment是一个文档片段,相比较下面这种代码的好处是
for(var i = 0;i<100;i++){
var btn=document.createElement('button');
body.appendChild(btn);
}
前者页面只重排一次,后者页面重排了100次;所以若遇到大模块添加dom时,最好使用fragment
第二步:为button绑定事件监听器,并设置时间戳
var btn = document.querySelectorAll('.btn');
var date1 = new Date();
for (var i = 0; i < btn.length; i++) {
(function(i) {
btn[i].addEventListener('click', function() {
console.log(i);
});
})(i)
}
第三步:给body绑定click事件,实现事件的委托
var date2 = new Date();
body.addEventListener('click', function(e) {
var element = e.target;
if (element.className == 'btn') {
console.log(element.id);
}
})
var date3 = new Date();
接下来,我们通过记录时间戳来分析这两种方式的具体性能表现。
console.log(date2 - date1);
console.log(date3 - date1);
通过改变button的数量,得到以下数据(单位:ms):
在360兼容模式下:
- 当button数量为100时,平均为 6 0
- 当button数量为400时,平均为 20 0
- 当button数量为1000时,平均为 48 0
在新版谷歌下:
- 当button数量为1000时,平均为 3 0
可见当页面中有大量元素需要绑定事件时,并不是所有的事件都会被触发,而这时对所有需要监听的元素都绑定事件处理器无疑是要花费代价的,而通过事件委托的方式可以很好的解决性能问题,不需要为每个元素都绑定事件监听器。但是要写一些逻辑代码来判断事件源。所以,如果你的web项目对性能要求极为苛刻,事件委托也不失于一种优雅的选择
JavaScript事件参考资源
PS:这里再为大家附上javascript系统自带事件参考表供大家参考查询:
javascript事件与功能说明大全: http://tools.jb51.net/table/javascript_event
更多关于JavaScript相关内容可查看本站专题:《JavaScript事件相关操作与技巧大全》、《JavaScript常用函数技巧汇总》、《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》及《JavaScript数学运算用法总结》
希望本文所述对大家JavaScript程序设计有所帮助。