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 相关文章推荐
baidu博客的编辑友情链接的新的层窗口!经典~支持【FF】
Feb 09 Javascript
JQuery 1.3.2以上版本中出现pareseerror错误的解决方法
Jan 11 Javascript
js修改地址栏URL参数解决url参数问题
Dec 15 Javascript
JS面向对象基础讲解(工厂模式、构造函数模式、原型模式、混合模式、动态原型模式)
Aug 16 Javascript
jQuery中$.get、$.post、$.getJSON和$.ajax的用法详解
Nov 19 Javascript
jQuery过滤选择器详解
Jan 13 Javascript
JS简单模拟触发按钮点击功能的方法
Nov 30 Javascript
jquery实现瀑布流效果 jquery下拉加载新数据
Dec 12 Javascript
JS实现websocket长轮询实时消息提示的效果
Oct 10 Javascript
Element-UI Table组件上添加列拖拽效果实现方法
Apr 14 Javascript
ng-repeat指令在迭代对象时的去重方法
Oct 02 Javascript
利用 JavaScript 实现并发控制的示例代码
Dec 31 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微信开发之模板消息回复
2016/06/24 PHP
Laravel最佳分割路由文件(routes.php)的方式
2016/08/04 PHP
PHP设计模式概论【概念、分类、原则等】
2020/05/01 PHP
图片自动缩小 点击放大
2008/07/07 Javascript
浅析offsetLeft,Left,clientLeft之间的区别
2013/11/30 Javascript
JavaScript仿淘宝页面图片滚动加载及刷新回顶部的方法解析
2016/05/24 Javascript
jQuery+ajax+asp.net获取Json值的方法
2016/06/08 Javascript
轻松掌握JavaScript单例模式
2016/08/25 Javascript
React实现点击删除列表中对应项
2017/01/10 Javascript
JavaScript使用原型和原型链实现对象继承的方法详解
2017/04/05 Javascript
BootStrap导航栏问题记录
2017/07/31 Javascript
vue2.0 datepicker使用方法
2018/02/04 Javascript
微信小程序WebSocket实现聊天对话功能
2018/07/06 Javascript
socket io与vue-cli的结合使用的示例代码
2018/11/01 Javascript
JS div匀速移动动画与变速移动动画代码实例
2019/03/26 Javascript
如何检查一个对象是否为空
2019/04/11 Javascript
150行Node.js实现的dns代理工具
2019/08/02 Javascript
layui点击按钮页面会自动刷新的解决方案
2019/10/25 Javascript
微信小程序使用GoEasy实现websocket实时通讯
2020/05/19 Javascript
vue中解决拖拽改变存在iframe的div大小时卡顿问题
2020/07/22 Javascript
从零学python系列之从文件读取和保存数据
2014/05/23 Python
windows10下python3.5 pip3安装图文教程
2018/04/02 Python
selenium设置proxy、headers的方法(phantomjs、Chrome、Firefox)
2018/11/29 Python
python实现接口并发测试脚本
2019/06/25 Python
Python使用docx模块实现刷题功能代码
2020/02/13 Python
django 多数据库及分库实现方式
2020/04/01 Python
Pytorch实现将模型的所有参数的梯度清0
2020/06/24 Python
python利用google翻译方法实例(翻译字幕文件)
2020/09/21 Python
英国户外装备和冒险服装零售商:alloutdoor
2018/01/30 全球购物
介绍一下UNIX启动过程
2013/11/14 面试题
写自荐信的七个技巧
2013/10/15 职场文书
教师队伍管理制度
2014/01/14 职场文书
三项教育活动实施方案
2014/03/30 职场文书
pytorch中Schedule与warmup_steps的用法说明
2021/05/24 Python
Python天气语音播报小助手
2021/09/25 Python
教你使用Python获取QQ音乐某个歌手的歌单
2022/04/03 Python