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用Date对象处理时间实现思路及代码
Jan 31 Javascript
jquery获得keycode的示例代码
Dec 30 Javascript
jQuery如何实现点击页面获得当前点击元素的id或其他信息
Jan 09 Javascript
JS打开新窗口防止被浏览器阻止的方法
Jan 03 Javascript
在JavaScript中操作时间之getMonth()方法的使用
Jun 10 Javascript
使用javascript将时间转换成今天,昨天,前天等格式
Jun 25 Javascript
jQuery检查事件是否触发的方法
Jun 26 Javascript
浅谈Angular的$q, defer, promise
Dec 20 Javascript
浅谈JS中的反柯里化( uncurrying)
Aug 17 Javascript
原生实现一个react-redux的代码示例
Jun 08 Javascript
express+vue+mongodb+session 实现注册登录功能
Dec 06 Javascript
socket在egg中的使用实例代码详解
May 30 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 空格,换行,跳格使用说明
2009/12/18 PHP
php基于curl扩展制作跨平台的restfule 接口
2015/05/11 PHP
PHP中的随机性 你觉得自己幸运吗?
2016/01/22 PHP
php利用gd库为图片添加水印
2016/11/09 PHP
PHP删除数组中指定值的元素常用方法实例分析【4种方法】
2018/08/21 PHP
在laravel5.2中实现点击用户头像更改头像的方法
2019/10/14 PHP
Gambit vs CL BO3 第一场 2.13
2021/03/10 DOTA
jquery提示 &quot;object expected&quot;的解决方法
2009/12/13 Javascript
javascript 鼠标悬浮图片显示原图 移出鼠标后原图消失(多图)
2009/12/28 Javascript
javaScript checkbox 全选/反选及批量删除
2010/04/28 Javascript
基于jquery跨浏览器显示的file上传控件
2011/10/24 Javascript
scrollWidth,clientWidth,offsetWidth的区别
2015/01/13 Javascript
jquery trigger实现联动的方法
2016/02/29 Javascript
简单解析JavaScript中的__proto__属性
2016/05/10 Javascript
浅析Node.js实现HTTP文件下载
2016/08/05 Javascript
nodejs 搭建简易服务器的图文教程(推荐)
2017/07/18 NodeJs
javascript 缓冲运动框架的实现
2017/09/29 Javascript
解决vue组件中使用v-for出现告警问题及v for指令介绍
2017/11/11 Javascript
vuex页面刷新后数据丢失的方法
2019/01/17 Javascript
uni-app微信小程序登录并使用vuex存储登录状态的思路详解
2019/11/04 Javascript
浅谈vuex的基本用法和mapaction传值问题
2019/11/08 Javascript
JS实现盒子拖拽效果
2020/02/06 Javascript
Python使用代理抓取网站图片(多线程)
2014/03/14 Python
Python中多线程的创建及基本调用方法
2016/07/08 Python
python3 破解 geetest(极验)的滑块验证码功能
2018/02/24 Python
python使用Turtle库绘制动态钟表
2018/11/19 Python
python使用pyecharts库画地图数据可视化的实现
2020/03/25 Python
Python实现弹球小游戏
2020/08/01 Python
Django扫码抽奖平台的配置过程详解
2021/01/14 Python
轻松掌握CSS3中的字体大小单位rem的使用方法
2016/05/24 HTML / CSS
Raffaello Network德国:意大利拉斐尔时尚购物网
2019/05/01 全球购物
澳洲最大的时尚奢侈品电商平台:Cettire
2020/06/15 全球购物
廉洁校园实施方案
2014/05/25 职场文书
实习介绍信范文
2015/05/05 职场文书
spring项目中切面及AOP的使用方法
2021/06/26 Java/Android
Python爬虫中urllib3与urllib的区别是什么
2021/07/21 Python