javascript事件监听与事件委托实例详解


Posted in Javascript onAugust 16, 2019

本文实例讲述了javascript事件监听与事件委托。分享给大家供大家参考,具体如下:

事件监听与事件委托

在js中,常用到element.addEventListener()来进行事件的监听。但是当页面中存在大量需要绑定事件的元素时,这种方式可能会带来性能影响。此时,我们可以用事件委托的方式来进行事件的监听。

每个事件都经历三个阶段

  • 捕获
  • 到达目标
  • 冒泡

事件委托需要用到事件的冒泡,冒泡就是事件发生时,上层会一层一层的接收这个事件。

如下页面结构:

<body>
  <div id="div1">
    <div id="div2">
      <button>按钮</button>
    </div>
  </div>
</body>

当点击按钮,首先button接收到事件,然后向上层冒泡,接着id="div1"接收到事件,接着是id="div2",一直到达document的顶层。

所以可以添加一个事件处理器到父级,由他接收所有子节点的事件信息。这就是事件委托。

事件监听与事件委托性能比较

通过构建若干个button元素,并为其绑定事件监听器来比较事件监听与事件委托的性能。

1.构建若干个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

2.为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)
}

3.给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项目对性能要求极为苛刻,事件委托也不失于一种优雅的选择

PS:这里再为大家附上javascript系统自带事件参考表供大家参考查询:

javascript事件与功能说明大全:
http://tools.3water.com/table/javascript_event

更多关于JavaScript相关内容可查看本站专题:《JavaScript事件相关操作与技巧大全》、《JavaScript常用函数技巧汇总》、《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
才发现的超链接js导致网页中GIF动画停止的解决方法
Nov 02 Javascript
jQuery数组处理代码详解(含实例演示)
Feb 03 Javascript
jquery获取iframe中的dom对象(两种方法)
Jul 02 Javascript
javascript实现uploadify上传格式以及个数限制
Nov 23 Javascript
学习JavaScript设计模式(策略模式)
Nov 26 Javascript
JavaScript实现星星等级评价功能
Mar 22 Javascript
浅谈Redux中间件的实践
Jul 27 Javascript
解决vue移动端适配问题
Dec 12 Javascript
JS中的算法与数据结构之链表(Linked-list)实例详解
Aug 20 Javascript
ES5新增数组的实现方法
May 12 Javascript
JavaScript 几种循环方式以及模块化的总结
Sep 03 Javascript
vue实现动态给id赋值,点击事件获取当前点击的元素的id操作
Nov 09 Javascript
使用Vue-Awesome-Swiper实现旋转叠加轮播效果&amp;平移轮播效果
Aug 16 #Javascript
详解Vue中组件传值的多重实现方式
Aug 16 #Javascript
详解vue+axios给开发环境和生产环境配置不同的接口地址
Aug 16 #Javascript
JavaScript JSON数据处理全集(小结)
Aug 15 #Javascript
JointJS JavaScript流程图绘制框架解析
Aug 15 #Javascript
基于vue写一个全局Message组件的实现
Aug 15 #Javascript
vue element-ui table组件动态生成表头和数据并修改单元格格式 父子组件通信
Aug 15 #Javascript
You might like
PHP动态创建Web站点的方法
2011/08/14 PHP
PHP获取当前页面完整URL的实现代码
2013/06/10 PHP
PHP中的多行字符串传递给JavaScript的两种方法
2014/06/19 PHP
php实现有趣的人品测试程序实例
2015/06/08 PHP
php使用curl详细解析及问题汇总
2016/08/11 PHP
php封装的smartyBC类完整实例
2016/10/19 PHP
php格式文件打开的四种方法
2018/02/24 PHP
基于PHP+mysql实现新闻发布系统的开发
2020/08/06 PHP
PHP实现爬虫爬取图片代码实例
2021/03/03 PHP
js类中获取外部函数名的方法
2007/08/19 Javascript
让人印象深刻的10个jQuery手风琴效果应用
2012/05/08 Javascript
Bootstrap开发实战之第一次接触Bootstrap
2016/06/02 Javascript
走进javascript——不起眼的基础,值和分号
2017/02/24 Javascript
vue.js项目中实用的小技巧汇总
2017/11/29 Javascript
javascript中的隐式调用
2018/02/10 Javascript
JavaScript中利用Array filter() 方法压缩稀疏数组
2018/02/24 Javascript
使用vuex的state状态对象的5种方式
2018/04/19 Javascript
基于Koa2写个脚手架模拟接口服务的方法
2018/11/27 Javascript
bootstrap-paginator服务器端分页使用方法详解
2020/02/13 Javascript
解决Vue-cli3没有vue.config.js文件夹及配置vue项目域名的问题
2020/12/04 Vue.js
浅谈python中scipy.misc.logsumexp函数的运用场景
2016/06/23 Python
Python Flask前后端Ajax交互的方法示例
2018/07/31 Python
python3.7 sys模块的具体使用
2019/07/22 Python
使用Python刷淘宝喵币(低阶入门版)
2019/10/30 Python
Python Pandas 转换unix时间戳方式
2019/12/07 Python
django框架中ajax的使用及避开CSRF 验证的方式详解
2019/12/11 Python
最新Python idle下载、安装与使用教程图文详解
2020/11/28 Python
PyCharm 光标变成黑块的解决方式
2021/02/06 Python
HTML5之SVG 2D入门12—SVG DOM及DOM操作介绍
2013/01/30 HTML / CSS
世界上最大的二手相机店:KEN
2017/05/17 全球购物
澳大利亚连衣裙和女装在线:Esther
2017/11/11 全球购物
机电专业个人自荐信格式模板
2013/09/23 职场文书
销售工作人员的自我评价分享
2013/11/10 职场文书
社区七一党员活动方案
2014/01/25 职场文书
检举信的格式及范文
2014/04/04 职场文书
社区反邪教工作方案
2014/06/16 职场文书