彻底弄懂JS事件委托的概念和作用
一、写在前头
接到某厂电话问什么是事件代理的时候,一开始说addEventListener,然后他说直接绑定新的元素不会报dom不存在的错误吗?然后我就混乱了,我印象中这个方法是可以绑定新节点的。后面才知道,原来他要考察的是事件委托(代理)的原理,他指的是未来还不清楚会创建多少个节点,所以没办法实现给他们注册事件。
二、事件委托(事件代理)的作用?
为了方便理解,我先把事件委托的作用写一下。
- 支持为同一个DOM元素注册多个同类型事件
- 可将事件分成事件捕获和事件冒泡机制
例子解析:
- 注册多个事件
用以往注册事件的方法,如果存在多个事件,后注册的事件会覆盖先注册的事件
//index.html
<div id="div1"></div>
window.onload = function(){
let div1 = document.getElementById('div1');
div1.onclick = function(){
console.log('打印第一次')
}
div1.onclick = function(){
console.log('打印第二次')
}
}

可以看到第二个点击注册事件覆盖了第一个注册事件,只执行了console.log('打印第二次');
用addEventListener(type,listener,useCapture)实现
- type: 必须,String类型,事件类型
- listener: 必须,函数体或者JS方法
- useCapture: 可选,boolean类型。指定事件是否发生在捕获阶段。默认为false,事件发生在冒泡阶段
<div id="div1"></div>
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>
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')
})
}
//结果:打印div1 打印body

//当useCapture为true时,为事件捕获
<body>
<div id="div1"></div>
</body>
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')
})
}
//结果:打印body 打印div1

三、事件委托和新增节点绑定事件的关系?
事件委托的优点:
- 提高性能:每一个函数都会占用内存空间,只需添加一个事件处理程序代理所有事件,所占用的内存空间更少。
- 动态监听:使用事件委托可以自动绑定动态添加的元素,即新增的节点不需要主动添加也可以一样具有和其他元素一样的事件。
例子解析:
<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>
<body>
<div id="div">
<div class="div1">div1</div>
<div class="div2">div2</div>
</div>
</body>
虽然没有给div1和div2添加点击事件,但是无论是点击div1还是div2,都会打印当前节点。因为其父级绑定了点击事件,点击div1后冒泡上去的时候,执行父级的事件。
分别点击div1、div2、div3

这样无论后代新增了多少个节点,一样具有这个点击事件的功能。这一个就是考察者想要听到的答案。
彻底弄懂JS事件委托的概念和作用的更多相关文章
- js进阶 12-2 彻底弄懂JS的事件冒泡和事件捕获
js进阶 12-2 彻底弄懂JS的事件冒泡和事件捕获 一.总结 一句话总结:他们是描述事件触发时序问题的术语.事件捕获指的是从document到触发事件的那个节点,即自上而下的去触发事件.相反的,事件 ...
- JS事件委托的原理和应用
js事件委托也叫事件代理,实际上事件委托就是通过事件冒泡实现的,所谓的事件就是onclick,onmouseover,ondown等等,那么委托呢?委托就是指本来这个事是要你自己做的,但是你却让别人帮 ...
- JS事件委托学习(转)
JS 事件委托就是利用冒泡原理,把事件加到父级上触发,执行效果. 好处: 1.提高性能 2.新添加的元素还会有之前的事件 <</</</</li></ ...
- js事件委托 jQuery写法
http://www.cnblogs.com/liugang-vip/p/5616484.html 不是抄的,这篇文章写的细 这是js 事件委托写法 <!DOCTYPE html> < ...
- 原生js事件委托(事件代理)方法扩展
原生js事件委托(事件代理)方法扩展: 通过Node底层原型扩展委托方法 /** * 事件委托方法 * @param eventName {string}:事件名称,如'click' * @param ...
- 彻底弄懂JS的事件冒泡和事件捕获(不推荐阅读)
由于搬去敌台了,好久没来博客园,今天无意中翻到有“误认子弟”的评论,这里特意做个说明. 本文中关于事件冒泡和事件捕获的描述和例子都是OK的,错就错在后面用jquery去展示了利用事件冒泡的例子有误,其 ...
- 彻底弄懂JS的事件冒泡和事件捕获
先上结论:在事件执行流中有两种执行方式.一种是事件冒泡(即事件的执行顺序是从下往上执行的) ; 另一种是捕获(即事件的执行顺序是从上往下执行的); 阻止事件冒泡: return false; ...
- JavaScript中的this详解(彻底弄懂js中的this用法)!
要想学好js,那么其中那些特别令人混淆迷惑的知识点,就一定要弄清楚.this关键字就是其中让初学者比较迷惑的知识点之一,不过灵活运用this可以提升代码的性能和复用性,那么今天我就和大家一起来了解th ...
- js事件委托或事件代理
起因: 1.这是前端面试的经典题型,要去找工作的小伙伴看看还是有帮助的: 2.其实我一直都没弄明白,写这个一是为了备忘,二是给其他的知其然不知其所以然的小伙伴们以参考: 概述: 那什么叫事件委托呢?它 ...
随机推荐
- PyCharm 2017.2.3 版本在2017年9月7日发布,支持 Docker Compose
PyCharm是由JetBrains打造的一款Python IDE.PyCharm具备用于一般IDE的功能,比如, 调试.语法高亮.Project管理.代码跳转.智能提示.自动完成.单元测试.版本控制 ...
- JustOj 2009: P1016 (dp)
题目描述 有一个箱子容量为v(正整数,o≤v≤20000),同时有n个物品(o≤n≤30),每个物品有一个体积 (正整数).要求从 n 个物品中,任取若干个装入箱内,使箱子的剩余空间为最小. ...
- StructureStreaming与kafka集成读取数据必要的jar包
<dependency> <!--structurStreaming读取kafka1.0以下必须的jar--> <groupId>org.apache.spark& ...
- WinCHM 制作开发知识库,So easy!!!
开发过程中可能需要一些团队需要相互参照的东西,如前后台开发中的接口定义,团队开发规范,公用的类库,开发FAQ等 ,可以考虑用WinCHM这种工具制作开发知识库,然后发布至一Web服务器上,这样开发人员 ...
- Talented Chef ZOJ - 3778
As we all know, Coach Gao is a talented chef, because he is able to cook M dishes in the same time. ...
- ZYNQ跑系统 系列(二) petalinux方式移植linux petalinux-config遇到问题
petalinux-config --get-hw-description=. 报错 [INFO] sourcing bitbakeERROR: Failed to source bitbakeERR ...
- django的url配置
在一个请求到达的时候,最先达到的就是视图层,然后根据url映射到视图函数.这一部分我们来说明url的配置. 概述 为了给一个应用设计URL,你需要创建一个Python 模块,通常称为URLconf(U ...
- xtrabackup 对pxc节点进行备份恢复
xtrabackup 对pxc节点进行备份恢复 全量备份一个节点的数据,当节点挂掉时,使用备份恢复到最近状态,再启动节点加入集群. 备份 xtrabackup 命令小解释: --defaults-fi ...
- jQuery中prop和attr区别
问题 今天给一个button加onclick事件,由于最后button根据需要转成字符串,因此不能使用jQurey.click(),只能给button添加onclick属性的方式. 于是,$butto ...
- 教你用Visual Studio Code做PHP开发 - 微软官方工具,IDE中的黑马
转载于:http://bbs.wfun.com/thread-902655-1-1.html,仅供自己备忘 本文为我在智机网的原创 ] 关于Visual Studio Code,可能有的开发者很陌生 ...