事件委托的概念和原理
事件委托优点
- 减少DOM操作的,减少浏览器的重绘(repaint)和重排(reflow),从而提高性能;
- 减少内存空间的占用率,因为每一个函数都是一个对象,对象越多,内存占有率就越大,自然性能就越差,使用事件委托,只需要在其父元素中定义一个事件就可以。
- 适合事件委托的事件有:click,mousedown,mouseup,keydown,keyup,keypress
- 可以方便地动态添加和修改元素,不需要因为元素的改动而修改事件绑定。
为什么要用事件委托
dom需要有事件处理程序,我们都会直接给它设事件处理,那如果是很多的dom需要添加事件处理?比如我们有100个li,每个li都有相同的click点击事件,可能我们会用for循环的方法,来遍历所有的li,然后给它们添加事件,那这么做会存在什么影响呢?
- 操作DOM次数过多,造成浏览器的重排和重绘就越多;
- 每个事件都是一个对象,事件处理程序越多,占用的内存越多,影响前端性能;
事件委托(事件代理)原理——事件冒泡
事件委托利用事件冒泡(从最深的节点开始,然后逐步向上传播事件)只在他们的父元素上指定一个事件处理程序,就可以管理某一类型的的所有事件。
事件委托的实现
事件源: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后冒泡上去的时候,执行父级的事件。
这样无论后代新增了多少个节点,一样具有这个点击事件的功能。
事件委托的概念和原理相关推荐
- JS事件委托的概念和作用
一.写在前头 接到某厂电话问什么是事件代理的时候,一开始说addEventListener,然后他说直接绑定新的元素不会报dom不存在的错误吗?然后我就混乱了,我印象中这个方法是可以绑定新节点的.后面 ...
- JS 事件代理和事件委托
目录 事件委托的概念理解 为什么要用事件委托 事件委托的原理: 事件代理(委托)实现 总结: 事件委托的概念理解 为什么叫事件委托?它还有一个名字叫事件代理. JavaScript高级程序设计上讲:事 ...
- 事件委托、事件冒泡与事件捕获
目录 事件委托: 1.原理 2.实现 ①在介绍事件委托的方法之前,我们先来看一段一般方法的例子: ②那么我们用事件委托的方式做又会怎么样呢? ③要是每个li被点击的效果都不一样,那么用事件委托还有用吗 ...
- 事件委托技术原理和使用(js,jquery)
事件委托技术原理和使用(js,jquery) 原创 2016年03月10日 11:18:56 标签: 技术 / jquery / javascript 2555 一:事件委托技术原理 摘自http:/ ...
- JS事件委托或者事件代理原理以及实现
事件委托(事件代理)原理:简单的说就是将事件交由别人来执行,就是将子元素的事件通过冒泡的形式交由父元素来执行. 为什么要用时间委托? 在JavaScript中,添加到页面上的事件处理程序数量将直接关系 ...
- “约见”面试官系列之常见面试题之第六十六篇之事件委托的原理和实现(建议收藏)
事件委托(事件代理)原理:简单的说就是将事件交由别人来执行,就是将子元素的事件通过冒泡的形式交由父元素来执行. 为什么要用时间委托? 在JavaScript中,添加到页面上的事件处理程序数量将直接关系 ...
- js事件委托及其原理
什么是事件委托:通俗的讲,事件就是onclick,onmouseover,onmouseout,等就是事件,委托呢,就是让别人来做,这个事件本来是加在某些元素上的,然而你却加到别人身上来做,完成这个事 ...
- 什么是事件委托?事件委托的原理以及优缺点
事件委托又称事件代理, 下面将要将要简要叙述一下这种方法的原理及优点 一什么是事件委托? 我们看下面的例子: 假使我们需要对 3 个 li 元素添加点击事件: 传统的方法是分别给每个 li 元素绑定 ...
- js事件委托(事件代理)的原理以及优缺点
js事件委托/事件代理的原理以及优缺点 什么是事件委托:通俗的讲,事件就是onclick,onmouseover,onmouseout,等就是事件,委托呢,就是让别人来做,这个事件本来是加在某些元素上 ...
最新文章
- 第三十二课.脉冲神经网络SNN
- SQL2005合理的索引设计
- 实验三编程、编译、连接、跟踪
- 福禄克2500V数字绝缘电阻测试仪开箱与上手实测
- mysql高可用 持久层_MyBatis持久层框架使用总结 转载
- iOS13 已越狱 iOS12.4 已越狱
- java ee13_一口气了解多线程及其Java实现
- [html] canvas生成图片有没有跨域问题?如果有如何解决?
- ASP運行Excel.Application出錯
- java me手机版,一个经典的 JAVA ME 手机程序入门级源码
- 蓝桥杯2015年第六届C/C++B组国赛第一题-积分之迷
- 个人技能总结7--Apache服务器反向代理,负载均衡,热备份+Tomcat配置
- C1083,无法打开包括文件...
- 【Ydui.js】------- JavaScript 判断手机终端 例如:移动终端,苹果终端,ipad 终端 等;
- Python之---【pandas】pd.concat(df)、df.append(df)
- IE兼容模式文件上传所遇问题解决
- 理解分布式账本技术: 经济学视角
- java里的椭圆拟合_[求助]椭圆的跟踪拟合
- python界面小游戏贪吃蛇_用Python实现童年小游戏贪吃蛇
- java button中文乱码_java解决中文乱码的几种写法