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设置cookie、读取cookie、删除cookie
Apr 17 Javascript
Jquery插件仿百度搜索关键字自动匹配功能
May 11 Javascript
详细讲解JavaScript中的this绑定
Oct 10 Javascript
浅谈AngularJs指令之scope属性详解
Oct 24 Javascript
JS如何判断浏览器类型和详细区分IE各版本浏览器
Mar 04 Javascript
使用jQuery ajaxupload插件实现无刷新上传文件
Apr 23 jQuery
seajs模块压缩问题与解决方法实例分析
Oct 10 Javascript
基于mpvue小程序使用echarts画折线图的方法示例
Apr 24 Javascript
bootstrap table插件动态加载表头
Jul 19 Javascript
基于Web Audio API实现音频可视化效果
Jun 12 Javascript
Vue实现随机验证码功能
Dec 29 Vue.js
解决await在forEach中不起作用的问题
Feb 25 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的curl实现get和post的代码
2008/08/23 PHP
php去除重复字的实现代码
2011/09/16 PHP
PHP中array_slice函数用法实例详解
2014/11/25 PHP
PHP 爬取网页的主要方法
2018/07/13 PHP
php如何利用pecl安装mongodb扩展详解
2019/01/09 PHP
让iframe自适应高度(支持XHTML,支持FF)
2007/07/24 Javascript
使用JavaScript实现Java的List功能(实例讲解)
2013/11/07 Javascript
讲解JavaScript中for...in语句的使用方法
2015/06/03 Javascript
jQuery仿360导航页图标拖动排序效果代码分享
2015/08/24 Javascript
详解JavaScript中的4种类型识别方法
2015/09/14 Javascript
Node.js DES加密的简单实现
2016/07/07 Javascript
Google 地图控件集详解及实例代码
2016/08/06 Javascript
jQuery插件DataTable使用方法详解(.Net平台)
2016/12/22 Javascript
jquery submit()不能提交表单的解决方法
2017/04/24 jQuery
Angular4.0中引入laydate.js日期插件的方法教程
2017/12/25 Javascript
基于Swiper实现移动端页面图片轮播效果
2017/12/28 Javascript
使用mock.js随机数据和使用express输出json接口的实现方法
2018/01/07 Javascript
vue watch监听对象及对应值的变化详解
2018/02/24 Javascript
vue 使用html2canvas将DOM转化为图片的方法
2018/09/11 Javascript
详解处理Vue单页面应用SEO的另一种思路
2018/11/09 Javascript
vue通过指令(directives)实现点击空白处收起下拉框
2018/12/06 Javascript
vue实现二级导航栏效果
2019/10/19 Javascript
Vue项目vscode 安装eslint插件的方法(代码自动修复)
2020/04/15 Javascript
windows 10下安装搭建django1.10.3和Apache2.4的方法
2017/04/05 Python
python print 按逗号或空格分隔的方法
2018/05/02 Python
在python下实现word2vec词向量训练与加载实例
2020/06/09 Python
利用CSS3实现的文字定时向上滚动
2016/08/29 HTML / CSS
世界上第一个水枕头:Mediflow
2018/12/06 全球购物
美国购物网站:Clickhere2shop
2021/01/28 全球购物
What is EJB
2016/07/22 面试题
旅游管理本科生求职信
2013/10/14 职场文书
聘用意向书范本
2014/04/01 职场文书
会计电算化专业求职信
2014/06/10 职场文书
教育见习报告范文
2014/11/03 职场文书
2016年全国爱眼日宣传教育活动总结
2016/04/05 职场文书
Python实现数据的序列化操作详解
2022/07/07 Python