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 兼容FF的onmouseenter和onmouseleave的代码
Jul 19 Javascript
php与js的区别是什么
Aug 05 Javascript
JQuery对id中含有特殊字符的转义处理示例
Sep 06 Javascript
jQuery中insertBefore()方法用法实例
Jan 08 Javascript
jQuery老黄历完整实现方法
Jan 16 Javascript
javascript实现获取字符串hash值
May 10 Javascript
移动端脚本框架Hammer.js
Dec 15 Javascript
微信小程序 Nginx环境配置详细介绍
Feb 14 Javascript
jQuery EasyUI之验证框validatebox实例详解
Apr 10 jQuery
jQuery+PHP+Mysql实现抽奖程序
Apr 12 jQuery
详解微信第三方小程序代开发
Jun 23 Javascript
JS实现按比例缩小图片宽高
Aug 24 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设计模式 Adapter(适配器模式)
2011/06/26 PHP
PHP用星号隐藏部份用户名、身份证、IP、手机号等实例
2014/04/08 PHP
SESSION存放在数据库用法实例
2015/08/08 PHP
thinkPHP5.0框架开发规范简介
2017/03/25 PHP
js 实现打印网页中定义的部分内容的代码
2010/04/01 Javascript
jQuery中需要注意的细节问题小结
2011/12/06 Javascript
JavaScript DOM节点添加示例
2014/07/16 Javascript
angularJS 发起$http.post和$http.get请求的实现方法
2017/05/18 Javascript
详解用node编写自己的cli工具
2017/05/23 Javascript
快速理解 JavaScript 中的 LHS 和 RHS 查询的用法
2017/08/24 Javascript
Angular项目从新建、打包到nginx部署全过程记录
2017/12/09 Javascript
js构建二叉树进行数值数组的去重与优化详解
2018/03/26 Javascript
在vue中使用v-bind:class的选项卡方法
2018/09/27 Javascript
基于JS实现web端录音与播放功能
2019/04/17 Javascript
layui-select动态选中值的例子
2019/09/23 Javascript
使用layer弹窗提交表单时判断表单是否输入为空的例子
2019/09/26 Javascript
[05:14]辉夜杯主赛事第二日 RECAP精彩回顾
2015/12/27 DOTA
python实现apahce网站日志分析示例
2014/04/02 Python
django 自定义用户user模型的三种方法
2014/11/18 Python
python 中random模块的常用方法总结
2017/07/08 Python
python时间日期函数与利用pandas进行时间序列处理详解
2018/03/13 Python
python3实现磁盘空间监控
2018/06/21 Python
Python实现的从右到左字符串替换方法示例
2018/07/06 Python
Python获取网段内ping通IP的方法
2019/01/31 Python
pymysql之cur.fetchall() 和cur.fetchone()用法详解
2020/05/15 Python
基于python实现简单网页服务器代码实例
2020/09/14 Python
澳大利亚牛仔裤商店:Just Jeans
2016/10/13 全球购物
美国运动鞋和运动服零售商:Footaction
2017/04/07 全球购物
GoDaddy英国:全球排名第一的域名注册商
2018/06/08 全球购物
舞会礼服和舞会鞋:PromGirl
2019/04/22 全球购物
澳大利亚手袋、珠宝和在线时尚精品店:The Way
2019/12/21 全球购物
办公室副主任岗位职责
2013/11/25 职场文书
计算机学生求职信范文
2014/01/30 职场文书
2014年劳动部工作总结
2014/12/11 职场文书
早恋主题班会
2015/08/14 职场文书
python程序的组织结构详解
2021/12/06 Python