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面向对象成果 借国庆发布个最新作品与大家交流
Oct 03 Javascript
推荐一个自己用的封装好的javascript插件
Jan 29 Javascript
浅析JavaScript 调试方法和技巧
Oct 22 Javascript
谈一谈javascript中继承的多种方式
Feb 19 Javascript
JavaScript 函数的执行过程
May 09 Javascript
js实现鼠标单击Tab表单切换效果
May 16 Javascript
Vue使用Proxy监听所有接口状态的方法实现
Jun 07 Javascript
基于vue-cli搭建多模块且各模块独立打包的项目
Jun 12 Javascript
微信小程序一周时间表功能实现
Oct 17 Javascript
ES6使用 Array.includes 处理多重条件用法实例分析
Mar 02 Javascript
原生js实现日期选择插件
May 21 Javascript
原生js拖拽功能制作滑动条实例代码
Feb 05 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 Google的translate API代码
2008/12/10 PHP
Cakephp 执行主要流程
2010/03/24 PHP
php join函数应用
2011/05/04 PHP
PHP+MySQL投票系统的设计和实现分享
2012/09/23 PHP
php使用百度翻译api示例分享
2014/01/31 PHP
php中$_POST与php://input的区别实例分析
2015/01/07 PHP
PHP array_reverse() 函数原理及实例解析
2020/07/14 PHP
JavaScript中Array 对象相关的几个方法
2006/12/22 Javascript
javascript陷阱 一不小心你就中招了(字符运算)
2013/11/10 Javascript
浅析Javascript中“==”与“===”的区别
2014/12/23 Javascript
javascript中关于&amp;&amp; 和 || 表达式的小技巧分享
2015/04/10 Javascript
javascript电商网站抢购倒计时效果实现
2015/11/19 Javascript
javascript实现tab响应式切换特效
2016/01/29 Javascript
JS实现1000以内被3或5整除的数字之和
2016/02/18 Javascript
一个简单不报错的summernote 图片上传案例
2016/07/11 Javascript
Bootstrap 网站实例之单页营销网站
2016/10/20 Javascript
微信小程序 scroll-view实现上拉加载与下拉刷新的实例
2017/01/21 Javascript
浅谈vue路径优化之resolve
2017/10/13 Javascript
Vue实现导航栏点击当前标签变色功能
2020/08/19 Javascript
解决使用layui对select append元素无效或者未及时更新的问题
2019/09/18 Javascript
简明 Python 基础学习教程
2007/02/08 Python
在Mac OS系统上安装Python的Pillow库的教程
2015/11/20 Python
python利用Guetzli批量压缩图片
2017/03/23 Python
python实现下载pop3邮件保存到本地
2018/06/19 Python
Django 多环境配置详解
2019/05/14 Python
python3连接MySQL8.0的两种方式
2020/02/17 Python
Docker如何部署Python项目的实现详解
2020/10/26 Python
快速实现一个简单的canvas迷宫游戏的示例
2018/07/04 HTML / CSS
找到不普通的东西:Bonanza
2016/10/20 全球购物
微软新西兰官方网站:Microsoft New Zealand
2018/08/17 全球购物
大学生评语大全
2014/04/18 职场文书
文明之星事迹材料
2014/05/09 职场文书
入党积极分子培养人意见
2015/06/02 职场文书
Vue实现tab导航栏并支持左右滑动功能
2021/06/28 Vue.js
关于nginx 实现jira反向代理的问题
2021/09/25 Servers
浅析Python中的随机采样和概率分布
2021/12/06 Python