当一个事件发生在具有父元素的元素上,现代浏览器会运行两个不同的阶段,
捕获阶段和冒泡阶段,二者是相反的流程。
- 捕获阶段
- 浏览器检查元素的最外层祖先
<html>,是否在捕获阶段中注册了某个事件处理程序,如果是,则运行它;- 然后,它移动到
<html>中单击元素的下一个祖先元素,并执行相同的操作,然后是单击元素再下一个祖先元素,依此类推,直到到达实际点击的元素。
- 冒泡阶段
- 浏览器检查实际点击的元素是否在冒泡阶段中注册了某个事件处理程序,如果是,则运行它;
- 然后,它移动到下一个直接的祖先元素,并做同样的事情,然后是下一个,等等,直到它到达
<html>元素。
- 我们在事件对象上调用
stopPropagation()函数,这样它就只会让当前事件处理程序运行,不会在冒泡链上进一步扩大,因此将不会有更多事件处理器被运行(不会向上冒泡)。
// 伪代码
video.onclick = function(event) {
event.stopPropagation()
video.play()
}
⚠️ 默认情况下,所有事件处理程序都是在冒泡阶段注册的,这在大多数情况下更有意义。如果您真的想在捕获阶段注册一个事件,那么您可以通过使用addEventListener()注册您的处理程序,并将可选的第三个属性设置为true。
- 事件委托
冒泡还允许我们利用事件委托,如果你想要在大量子元素中单击任何一个都可以运行一段代码,您可以将事件监听器设置在其父节点上,并让子节点上发生的事件冒泡到父节点上,而不是每个子节点单独设置事件监听器。
一个很好的例子是一系列,列表项,如果你想让每个列表项被点击时弹出一条信息,您可以将
click单击事件监听器设置在父元素<ul>上,这样事件就会从列表项冒泡到其父元素<ul>上。这个概念在 How JavaScript Event Delegation Works 文章中有更多的解释.







网友评论