事件委托优点

  1. 减少DOM操作的,减少浏览器的重绘(repaint)和重排(reflow),从而提高性能;
  2. 减少内存空间的占用率,因为每一个函数都是一个对象,对象越多,内存占有率就越大,自然性能就越差,使用事件委托,只需要在其父元素中定义一个事件就可以。
  3. 适合事件委托的事件有:click,mousedown,mouseup,keydown,keyup,keypress
  4. 可以方便地动态添加和修改元素,不需要因为元素的改动而修改事件绑定。

为什么要用事件委托

dom需要有事件处理程序,我们都会直接给它设事件处理,那如果是很多的dom需要添加事件处理?比如我们有100个li,每个li都有相同的click点击事件,可能我们会用for循环的方法,来遍历所有的li,然后给它们添加事件,那这么做会存在什么影响呢?

  1. 操作DOM次数过多,造成浏览器的重排和重绘就越多;
  2. 每个事件都是一个对象,事件处理程序越多,占用的内存越多,影响前端性能;

事件委托(事件代理)原理——事件冒泡

事件委托利用事件冒泡(从最深的节点开始,然后逐步向上传播事件)只在他们的父元素上指定一个事件处理程序,就可以管理某一类型的的所有事件。

事件委托的实现

事件源:Event对象提供了一个属性叫target,可以返回事件的目标节点,标准浏览器用ev.target,IE浏览器用event.srcElement,

1,父元素绑定事件

<div id="box"><input type="button" id="add" value="添加" /><input type="button" id="remove" value="删除" /><input type="button" id="move" value="移动" /><input type="button" id="select" value="选择" />
</div>
window.onload = function(){var oBox = document.getElementById("box");oBox.onclick = function (ev) {var ev = ev || window.event;var target = ev.target || ev.srcElement;if(target.nodeName.toLocaleLowerCase() == 'input'){switch(target.id){case 'add' :alert('添加');break;case 'remove' :alert('删除');break;case 'move' :alert('移动');break;case 'select' :alert('选择');break;}}}   }
//或者使用oBox.addEventListener(时间类型,函数,默认false为时间冒泡),下面我会讲到

上述target只是获得了当前节点位置,但不知道具体节点名称,所以使用nodeName来获取标签名,这里获得但标签名是大写INPUT

除来获取标签名,这里也可以获取当前点击标签但其他属性,例如:ev.target.id, ev.target.value, ev.target.type.

这里用父级div做事件处理,当input被点击时,由于冒泡原理,事件就会冒泡到div上,因为div上有点击事件,所以事件就会触发


接下来我们再看一个例子  addEventListener

<div id="div1">点击
</div><script>window.onload = function(){let div1 = document.getElementById('div1');div1.onclick = function(){console.log('打印第一次')}div1.onclick = function(){console.log('打印第二次')}}
</script>

可以看到第二个点击注册事件覆盖了第一个注册事件,只执行了console.log('打印第二次');


用addEventListener(type,listener,useCapture)实现

  • type: 必须,String类型,事件类型
  • listener: 必须,函数体或者JS方法
  • useCapture: 可选,boolean类型。指定事件是否发生在捕获阶段。默认为false,事件发生在冒泡阶段
window.onload = function(){let div1 = document.getElementById('div1');div1.addEventListener('click',function(){console.log('打印第一次')})div1.addEventListener('click',function(){console.log('打印第二次')})}

我们看一下效果


可以看到两个注册事件都成功触发了。 useCapture是事件委托的关键。


事件捕获和事件冒泡机制

事件捕获:当一个事件触发后,从Window对象触发,不断经过下级节点,直到目标节点。在事件到达目标节点之前的过程就是捕获阶段。所有经过的节点,都会触发对应的事件

事件冒泡:当事件到达目标节点后,会沿着捕获阶段的路线原路返回。同样,所有经过的节点,都会触发对应的事件

例子:假设有body和body节点下的div1均有绑定了一个注册事件.
效果:
    当为事件捕获(useCapture:true)时,先执行body的事件,再执行div的事件
    当为事件冒泡(useCapture:false)时,先执行div的事件,再执行body的事件

//当useCapture为默认false时,为事件冒泡
<body><div id="div1"></div>
</body><script>window.onload = function(){let body = document.querySelector('body');let div1 = document.getElementById('div1');body.addEventListener('click',function(){console.log('打印body')})div1.addEventListener('click',function(){console.log('打印div1')})}
</script>//结果:打印div1  打印body

//当useCapture为true时,为事件捕获
<body><div id="div1"></div>
</body><script>window.onload = function(){let body = document.querySelector('body');let div1 = document.getElementById('div1');body.addEventListener('click',function(){console.log('打印body')},true)div1.addEventListener('click',function(){console.log('打印div1')})}
</script>//结果:打印body   打印div1


接下来我们看一下事件委托和新增节点绑定事件之间的关系

<body><div id="div"><div class="div1">div1</div><div class="div2">div2</div></div>
</body><script>window.onload = function(){let div = document.getElementById('div');div.addEventListener('click',function(e){console.log(e.target)})let div3 = document.createElement('div');div3.setAttribute('class','div3')div3.innerHTML = 'div3';div.appendChild(div3)}
</script>

依次点击子div:

虽然没有给div1和div2添加点击事件,但是无论是点击div1还是div2,都会打印当前节点。因为其父级绑定了点击事件,点击div1后冒泡上去的时候,执行父级的事件。

这样无论后代新增了多少个节点,一样具有这个点击事件的功能。

事件委托的概念和原理相关推荐

  1. JS事件委托的概念和作用

    一.写在前头 接到某厂电话问什么是事件代理的时候,一开始说addEventListener,然后他说直接绑定新的元素不会报dom不存在的错误吗?然后我就混乱了,我印象中这个方法是可以绑定新节点的.后面 ...

  2. JS 事件代理和事件委托

    目录 事件委托的概念理解 为什么要用事件委托 事件委托的原理: 事件代理(委托)实现 总结: 事件委托的概念理解 为什么叫事件委托?它还有一个名字叫事件代理. JavaScript高级程序设计上讲:事 ...

  3. 事件委托、事件冒泡与事件捕获

    目录 事件委托: 1.原理 2.实现 ①在介绍事件委托的方法之前,我们先来看一段一般方法的例子: ②那么我们用事件委托的方式做又会怎么样呢? ③要是每个li被点击的效果都不一样,那么用事件委托还有用吗 ...

  4. 事件委托技术原理和使用(js,jquery)

    事件委托技术原理和使用(js,jquery) 原创 2016年03月10日 11:18:56 标签: 技术 / jquery / javascript 2555 一:事件委托技术原理 摘自http:/ ...

  5. JS事件委托或者事件代理原理以及实现

    事件委托(事件代理)原理:简单的说就是将事件交由别人来执行,就是将子元素的事件通过冒泡的形式交由父元素来执行. 为什么要用时间委托? 在JavaScript中,添加到页面上的事件处理程序数量将直接关系 ...

  6. “约见”面试官系列之常见面试题之第六十六篇之事件委托的原理和实现(建议收藏)

    事件委托(事件代理)原理:简单的说就是将事件交由别人来执行,就是将子元素的事件通过冒泡的形式交由父元素来执行. 为什么要用时间委托? 在JavaScript中,添加到页面上的事件处理程序数量将直接关系 ...

  7. js事件委托及其原理

    什么是事件委托:通俗的讲,事件就是onclick,onmouseover,onmouseout,等就是事件,委托呢,就是让别人来做,这个事件本来是加在某些元素上的,然而你却加到别人身上来做,完成这个事 ...

  8. 什么是事件委托?事件委托的原理以及优缺点

    事件委托又称事件代理, 下面将要将要简要叙述一下这种方法的原理及优点 一什么是事件委托? 我们看下面的例子: 假使我们需要对 3 个 li 元素添加点击事件: 传统的方法是分别给每个 li 元素绑定 ...

  9. js事件委托(事件代理)的原理以及优缺点

    js事件委托/事件代理的原理以及优缺点 什么是事件委托:通俗的讲,事件就是onclick,onmouseover,onmouseout,等就是事件,委托呢,就是让别人来做,这个事件本来是加在某些元素上 ...

最新文章

  1. 第三十二课.脉冲神经网络SNN
  2. SQL2005合理的索引设计
  3. 实验三编程、编译、连接、跟踪
  4. 福禄克2500V数字绝缘电阻测试仪开箱与上手实测
  5. mysql高可用 持久层_MyBatis持久层框架使用总结 转载
  6. iOS13 已越狱 iOS12.4 已越狱
  7. java ee13_一口气了解多线程及其Java实现
  8. [html] canvas生成图片有没有跨域问题?如果有如何解决?
  9. ASP運行Excel.Application出錯
  10. java me手机版,一个经典的 JAVA ME 手机程序入门级源码
  11. 蓝桥杯2015年第六届C/C++B组国赛第一题-积分之迷
  12. 个人技能总结7--Apache服务器反向代理,负载均衡,热备份+Tomcat配置
  13. C1083,无法打开包括文件...
  14. 【Ydui.js】------- JavaScript 判断手机终端 例如:移动终端,苹果终端,ipad 终端 等;
  15. Python之---【pandas】pd.concat(df)、df.append(df)
  16. IE兼容模式文件上传所遇问题解决
  17. 理解分布式账本技术: 经济学视角
  18. java里的椭圆拟合_[求助]椭圆的跟踪拟合
  19. python界面小游戏贪吃蛇_用Python实现童年小游戏贪吃蛇
  20. java button中文乱码_java解决中文乱码的几种写法

热门文章

  1. 重看《我爱我家》:一部电视剧背后的当代史
  2. 顽固湿疹医案一则(后诊断为白疕,即牛皮癣)
  3. lda主题演化与热度python实现
  4. iOS apple Pay 教程
  5. 用Django创建一个简单网页
  6. 【故宫,下雪了】一夜醒来,故宫完成秋冬交接,来自北方的故事纷纷踏雪而来(内含多份源码)
  7. 兴奋性氨基酸是什么?
  8. R语言提取单点的cru格点数据
  9. java实现excel批量导入图片到服务器
  10. Android使用BACnet协议进行数据读写测试