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 相关文章推荐
JavaScript 数组的 uniq 方法
Jan 23 Javascript
javascript:void(0)使用探讨
Aug 27 Javascript
jQuery中的val()示例应用
Feb 26 Javascript
jsMind通过鼠标拖拽的方式调整节点位置
Apr 13 Javascript
js实现完美兼容各大浏览器的人民币大小写相互转换
Oct 29 Javascript
JavaScript匿名函数之模仿块级作用域
Dec 12 Javascript
js防阻塞加载的实现方法
Sep 09 Javascript
vue2.0父子组件及非父子组件之间的通信方法
Jan 21 Javascript
基于JS实现网页中的选项卡(两种方法)
Jun 16 Javascript
vue实现2048小游戏功能思路详解
May 09 Javascript
node微信开发之获取access_token+自定义菜单
Mar 17 Javascript
JSONObject与JSONArray使用方法解析
Sep 28 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下常用正则表达式整理
2010/10/26 PHP
PHP函数extension_loaded()用法实例
2015/01/19 PHP
PHP使用http_build_query()构造URL字符串的方法
2016/04/02 PHP
js 浏览本地文件夹系统示例代码
2013/10/24 Javascript
JS(JQuery)操作Array的相关方法介绍
2014/02/11 Javascript
Node.js 文件夹目录结构创建实例代码
2016/07/08 Javascript
轻松掌握JavaScript策略模式
2016/08/25 Javascript
解析ajaxFileUpload 异步上传文件简单使用
2016/12/30 Javascript
jQuery DateTimePicker 日期和时间插件示例
2017/01/22 Javascript
JS的Ajax与后端交互数据的实例
2018/08/08 Javascript
微信小程序实现slideUp、slideDown滑动效果及点击空白隐藏功能示例
2018/12/11 Javascript
layer实现弹出层自动调节位置
2019/09/05 Javascript
初学Python实用技巧两则
2014/08/29 Python
使用IPython来操作Docker容器的入门指引
2015/04/08 Python
Python编程入门之Hello World的三种实现方式
2015/11/13 Python
Python3内置模块之json编解码方法小结【推荐】
2020/12/09 Python
Python多版本开发环境管理工具介绍
2019/07/03 Python
python抓取多种类型的页面方法实例
2019/11/20 Python
浅谈Django中的QueryDict元素为数组的坑
2020/03/31 Python
关于tf.matmul() 和tf.multiply() 的区别说明
2020/06/18 Python
Python reques接口测试框架实现代码
2020/07/28 Python
简单html5代码获取地理位置
2014/03/31 HTML / CSS
使用HTML5 Geolocation实现一个距离追踪器
2018/04/09 HTML / CSS
台湾租车首选品牌:IWS艾维士租车
2019/05/03 全球购物
Kipling意大利官网:世界著名的时尚休闲包袋品牌
2019/06/05 全球购物
白俄罗斯在线大型超市:e-dostavka.by
2019/07/25 全球购物
用C或者C++语言实现SOCKET通信
2015/02/24 面试题
海南地接欢迎词
2014/01/14 职场文书
阳光体育活动实施方案
2014/05/25 职场文书
企业优秀员工事迹材料
2014/05/28 职场文书
乳制品整治工作方案
2014/05/29 职场文书
毕业生自荐材料范文
2014/12/30 职场文书
老兵退伍感言
2015/08/03 职场文书
2016银行招聘自荐信
2016/01/28 职场文书
pytorch 实现在测试的时候启用dropout
2021/05/27 Python
mysql 生成连续日期及变量赋值
2022/03/20 MySQL