目录
- DOM事件流
- 常见面试题
- 事件冒泡与事件捕获
- 事件冒泡使用场景
- 事件捕获使用场景
- 事件冒泡和事件捕获区别
- 事件委托 - 利用事件冒泡机制
- 事件委托应用场景
- 支持事件委托的事件
- 事件委托的优缺点
DOM事件流
DOM事件流的三个阶段:捕获阶段 -> 目标阶段 -> 冒泡阶段
常见面试题
- 事件冒泡和委托是什么?有什么使用场景?
- 事件委托的优点和缺点
- JS事件绑定的原理
- 事件捕获和冒泡的过程
- 什么时候用冒泡?什么时候用捕获?
事件冒泡与事件捕获
目的:解决页面中的事件流(事件发生顺序)的问题
- 事件冒泡:事件从最深节点开始,然后逐步向上传播事件(从内到外)
- 事件捕获:事件从DOM树的根节点开始,然后逐级向下捕获到最具体的元素(目标元素)(从外到内)
当事件处于目标阶段时,事件调用顺序决定于绑定事件的书写顺序
事件冒泡使用场景
常见的使用场景就是事件委托。
通过事件委托,我们可以将事件处理程序绑定到父级元素,而不是直接绑定到每个子元素,从而减少了事件处理程序的数量,提高了性能和代码的可维护性。
事件捕获使用场景
事件捕获在实际开发中使用较少,但仍然有一些特定的使用场景:
- 事件处理程序前置操作:由于事件处理程序执行顺序的原因,可以在事件到达目标元素之前拦截事件并进行处理
- 高级事件处理:一些复杂的交互行为可能需要更细粒度的控制,而事件捕获提供了这种能力。例如,可以在事件捕获阶段使用stopPropagation方法停止事件的传播,以防止事件继续向下冒泡
事件冒泡和事件捕获区别
- 触发顺序:事件捕获先于事件冒泡触发。在事件捕获阶段,事件从DOM树的根节点向下传播到目标元素;在事件冒泡阶段,事件从目标元素向上冒泡到根节点
- 事件处理程序执行顺序:在事件捕获阶段,父级元素的事件处理程序会先于子级元素的事件处理程序执行;在事件冒泡阶段,子级元素的事件处理程序会先于父级元素的事件处理程序执行
- 默认阶段:大多数事件处理程序默认情况下在事件冒泡阶段触发,因此它们通常在事件冒泡阶段被执行。但是,可以使用addEventListener的第三个参数来指定事件是在事件捕获阶段还是事件冒泡阶段处理
事件委托 - 利用事件冒泡机制
事件委托:事件委托是利用事件冒泡原理实现的,就是事件目标自身不处理事件,而是把处理任务委托给其父元素或者祖先元素,甚至根元素
事件委托应用场景
- 为DOM中的很多元素绑定相同的事件
- 为DOM中尚不存在的元素绑定事件
使用事件委托时,如果注册到目标元素上的其他事件处理程序使用了
.stopPropagetion()
阻止了事件传播,那么事件委托就会失效
支持事件委托的事件
- 支持:click、mousedown、mouseup、keydown、keyup、keypress、change
- 不支持:focus、blur
事件委托的优缺点
优点:
- 减少事件注册,节省内存
- 简化了dom节点更新时,相应事件的更新,比如:不用在新添加的
li
上绑定click
事件,当删除某个li
时,不用解绑上面的click
事件
缺点:
- 事件委托基于冒泡,对于不冒泡的事件不支持
- 层级过多,冒泡过程中,可能会被某层阻止掉
- 理论上委托会导致浏览器频繁调用处理函数,所以建议就近委托,比如在
table
上代理td
,而不是在document
上代理td
- 把所有事件都用代理可能会出现事件误判