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 YUI 读码日记之 YAHOO.util.Dom - Part.3
Mar 22 Javascript
Clipboard.js 无需Flash的JavaScript复制粘贴库
Oct 02 Javascript
每天一篇javascript学习小结(Array数组)
Nov 11 Javascript
深入理解Node.js 事件循环和回调函数
Nov 02 Javascript
Bootstrap 设置datetimepicker在屏幕上面弹出设置方法
Mar 21 Javascript
JS实现图片放大镜插件详解
Nov 06 Javascript
vue checkbox 全选 数据的绑定及获取和计算方法
Feb 09 Javascript
vue动态绑定组件子父组件多表单验证功能的实现代码
May 14 Javascript
详解Chart.js轻量级图表库的使用经验
May 22 Javascript
Vue.js 实现数据展示全部和收起功能
Sep 05 Javascript
javacript replace 正则取字符串中的值并替换【推荐】
Sep 13 Javascript
vue响应式系统之observe、watcher、dep的源码解析
Apr 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中Array相关函数简介
2016/07/03 PHP
PHP如何读取由JavaScript设置的Cookie
2017/03/22 PHP
在Laravel中使用MongoDB的方法示例
2019/11/11 PHP
jQuery.Validate验证库的使用介绍
2013/04/26 Javascript
JQUERY dialog的用法详细解析
2013/12/19 Javascript
js中文逗号转英文实现
2014/02/11 Javascript
基于NodeJS的前后端分离的思考与实践(三)轻量级的接口配置建模框架
2014/09/26 NodeJs
jQuery基础知识小结
2014/12/22 Javascript
Javascript毫秒数用法实例
2015/02/05 Javascript
在父页面得到zTree已选中的节点的方法
2015/02/12 Javascript
微信小程序 wx.request(object) API详解及实例代码
2016/09/30 Javascript
解决同一页面中两个iframe互相调用jquery,js函数的方法
2016/12/12 Javascript
Vue.js仿Metronic高级表格(二)数据渲染
2017/04/19 Javascript
AngularJS实现的生成随机数与猜数字大小功能示例
2017/12/25 Javascript
element-ui 设置菜单栏展开的方法
2018/08/22 Javascript
使用Vue.js 和Chart.js制作绚丽多彩的图表
2019/06/15 Javascript
详解Vue后台管理系统开发日常总结(组件PageHeader)
2019/11/01 Javascript
Element-ui el-tree新增和删除节点后如何刷新tree的实例
2020/08/31 Javascript
[01:00:06]加油DOTA_EP01_网络版
2014/08/09 DOTA
[54:43]DOTA2-DPC中国联赛 正赛 CDEC vs Dynasty BO3 第一场 2月22日
2021/03/11 DOTA
使用python开发vim插件及心得分享
2014/11/04 Python
详解Python的Django框架中inclusion_tag的使用
2015/07/21 Python
快速解决安装python没有scripts文件夹的问题
2018/04/03 Python
python进行TCP端口扫描的实现
2018/12/21 Python
Python基于Opencv来快速实现人脸识别过程详解(完整版)
2019/07/11 Python
Pytorch实现基于CharRNN的文本分类与生成示例
2020/01/08 Python
浅谈CSS3中的变形功能-transform功能
2017/12/27 HTML / CSS
南京迈特望C/C++面试题
2012/07/09 面试题
项目资料员岗位职责
2013/12/10 职场文书
工作交流会欢迎词
2014/01/12 职场文书
班班通项目实施方案
2014/02/25 职场文书
孝敬父母的活动方案
2014/08/28 职场文书
学生会主席任命书
2015/09/21 职场文书
Java数据开发辅助工具Docker与普通程序使用方法
2021/09/15 Java/Android
MySQL实战记录之如何快速定位慢SQL
2022/03/23 MySQL
Nginx静态压缩和代码压缩提高访问速度详解
2022/05/30 Servers