DOM事件 : 捕获 和 冒泡
<html lang="en">
<body>
<table>
<tr>
<td>P</td>
</tr>
</table>
</body>
</html>
- 请问点击鼠标点击P的时候发生了什么?
- 答: 点击的时候事件会经历三个阶段:
- 捕获阶段(Capturing phase)—— 事件(从 Window)向下走近元素。
- 目标阶段(Target phase)—— 事件到达目标元素。
- 冒泡阶段(Bubbling phase)—— 事件从元素上开始冒泡。
- 答: 点击的时候事件会经历三个阶段:
- 捕获阶段(Capturing phase)
- 点击后,首先会从window开始运行,监听
- 然后在Dounment上运行,监听
- 然后是在上
<html>
运行,监听 - 然后是在上
<body>
运行,监听 - 然后是在上
<table>
运行,监听 - 然后是在上
<tbody>
运行,监听 - 直到最后在
<td>
上捕获P(此就到达目标属于(目标阶段)) - 一层一层的向下捕获
- 冒泡阶段(Bubbling phase)—— 事件从元素上开始冒泡
- 点击后,首先会从window开始运行,监听
- 首先从目标阶段
<td>
上开始运行,监听 - 然后是在
<tr>
上运行,监听 - 然后是在
<tbody>
上运行,监听 - 然后是在
<table>
上运行,监听 - 然后是在
<body>
上运行,监听 - 然后是在
<body>
上运行,监听 - 然后是在上
<html>
运行,监听 - 然后在Dounment上运行,监听
- 最后到底window
- 一层一层向上浮动
- 首先从目标阶段
-
点击
<td>
,事件首先通过祖先链向下到达元素(捕获阶段),然后到达目标(目标阶段),最后上升(冒泡阶段),在途中调用处理程序。 -
注意的是: 所有事件,都是先捕获阶段,然后冒泡阶段,按照这样的顺序进行的
捕获和冒泡不同阶段设置处理程序
- 处理程序的 capture 选项设置
elem.addEventListener(..., {capture: true})
//如果capture为 true,则在捕获阶段设置处理程序。
elem.addEventListener(..., {capture: true})
//如果capture为 false,则在冒泡阶段设置处理程序。
例子:
elem.addEventListener("click", e => alert(`Capturing: ${elem.tagName}`), true);
//捕获阶段设置处理程序
elem.addEventListener("click", e => alert(`Bubbling: ${elem.tagName}`));
// 冒泡阶段设置处理程序
DOM事件总结
当一个事件发生时 —— 发生该事件的嵌套最深的元素被标记为“目标元素”(event.target)。
- 然后,事件从文档根节点向下移动到 event.target,并在途中调用分配了 addEventListener(..., true) 的处理程序(true 是 {capture: true} 的一个简写形式)。 然后,在目标元素自身上调用处理程序。
- 然后,事件从 event.target 向上移动到根,调用使用 on 和没有第三个参数的,或者第三个参数为 false/{capture:false} 的 addEventListener 分配的处理程序。
- 每个处理程序都可以访问 event 对象的属性:
event.target
—— 引发事件的层级最深的元素--用户操作的元素event.currentTarget(=this)
—— 处理事件的当前元素(具有处理程序的元素)--程序员监听的元素event.eventPhase
—— 当前阶段。
事件委托
- 什么是事件委托?
- 答:监听祖先元素 : 捕获和冒泡允许我们实现一种被称为
事件委托
的强大的事件处理模式.- 如果我们有许多类似的方式要处理元素,那么就不必为每个元素分配一个处理程序 —— 而是将单个处理程序放在它们的共同祖先上 => 即监听祖先元素
- 优点: 1. 省内存 2. 可以监听动态元素
- 答:监听祖先元素 : 捕获和冒泡允许我们实现一种被称为