事件委托指的是事件可以绑定到其他节点上来触发你想要触发的目标节点的事件
首先有个问题,如果你想给同一个dom元素注册多个同类型事件,你会发现通过普通直接绑定无法实现,绑定多个事件只会出发最后一个绑定的事件。 如下图只会触发到第3个事件,控制台看到3
接下来就可以i通过事件处理器:addEventListener(type,listener,useCapture)实现
参数讲解:type:必填,字符串类型,指的是事件的类型;listener:必填,触发的事件,js方法或者函数体;useCapture:选填,布尔类型,默认false,即冒泡事件,true则为捕获事件;
事件捕获:当一个事件出发之后,从window对象触发,不断经过下级节点,直到目标节点。在时间到达目标节点之前的这个过程就是捕获过程,所有经过的节点,都会触发相对应的事件。
事件冒泡:和捕获过程相反,沿着捕获的路线原路返回,所有经过的节点时间都会被触发
效果举例:
冒泡事件:
控制台结果:点击div之后 ,会线触发div的事件,再向上一层冒泡,触发到body的事件;如果只点击到body是只会触发body的事件。
停止冒泡的方法:stoppropergation
捕获事件
若是给div和body都设置捕获(结果是2,1) 合情合理,
但是如果给div添加的是捕获事件的话,又是为什么呢?
按理说点击div应该从window向下到目标事件的这个捕获阶段内的事件都应该触发,那么就遇到了body的事件,body是默认冒泡,那么就从body向上冒泡,发现没有事件->执行完毕;之后执行之前的捕获的目标事件。(错误思路)
这个过程应该是先2,后1,如果这里存在疑问。(这是个错误的理解思路)-》这个时候需要知道事件流这个概念;
事件流
dom标准事件流包括三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段
- 事件捕获阶段:实际目标 (比如div)再捕获阶段不会接收事件,也就是在捕获过程中到达3就停止了
- 处于目标阶段:事件在<div>上发生并处理。但是事件处理会被看成是冒泡阶段的一部分
- 冒泡阶段:事件又传播回文档
不是所有的事件都要经历这三个阶段,所有事件都要经过前两个阶段,但是有的事件会跳过冒泡阶段,如,获得输入焦点的focus事件和失去输入焦点的blur事件。
冒泡型事件流,捕获型事件流
所以你把这个事件当成是一个环路,首先捕获阶段,会依次进行所有捕获的事件,之后会进行所有冒泡事件。
事件委托的优点:
- 提高性能:每一个函数都会占用内存空间,只需添加一个事件处理程序代理所有事件,所占用的内存空间更少。
- 动态监听:使用事件委托可以自动绑定动态添加的元素,即新增的节点不需要主动添加也可以一样具有和其他元素一样的事件。
阻止冒泡:stoppropagation()