Event flow
考虑这么个例子:
<div><button id="btn">Click Me!</button> </div>
哪怕一个web开发的初学者都会知道,当我们鼠标在button上点击时,会在button上触发一个click事件。但是:
- button是div的一个子Node;从界面上来看,在button里点击相当于在div里点击;那click事件也会触发在div上吗?
- 如果click事件也触发在div上,那它们会不会共用同一个事件对象?
- 如果click事件也触发在div上,谁的事件会先发生?
- click事件还会在哪些元素上面触发?
- 等等...
想解答上述问题,我们需要理解事件(Event)一个很重要的机制:事件流动(Event Flow)。
事件流动
DOM事件不单单只会在一个Element上触发,它还会流向其他Element。事件的流动通常会经历这么三个阶段:
捕获阶段 -> 目标阶段 -> 冒泡阶段
"eventPhase"
“eventPhase”是“Event”下的一个属性,它指明当前event属于那一个阶段。
“eventPhase”可能是一下其中一个值:
- Event.NONE,0,没有事件需要处理
- Event.CAPTURING_PHASE,1,捕获阶段
- Event.AT_TARGET,2,目标阶段,事件对象到达事件目标上
- Event.BUBBLING_PHASE,3,冒泡阶段
下面我们详细讨论一下这三个阶段。
捕获阶段(capture phase)
捕获阶段的定义如下(w3c):
The event object propagate through the target's ancestors from the defaultView to the target's parent.
事件对象在事件目标的祖先中上到下顺向传播,从最顶层的defaultView到事件目标的(直系)父元素。
捕获阶段发生在整个事件流动的开始。在这阶段里事件会从父(主干)到子(分支)由上往下传播,被元素一层层地捕获。
文章开头的例子里面,捕获阶段的click事件会依次在document、body、div上触发:
document 1v
body 2v
div 3 v button
一般我们没太大需要监听捕获阶段的事件;如果你确实希望这么做,需要将addEventListener
的第三个参数设置为true:
// 第三个参数设置是否为捕获阶段,默认为false
element.addEventListener('click', function() {}, true)
目标阶段(target phase)
目标阶段的定义是(w3c):
The event object arrive at the event object's event target.
事件对象到达事件目标。
例子里面,就是事件在button上触发的。addEventListener
可以监听目标阶段的事件:
element.addEventListener('click', function() {})
如果事件是不可冒泡的,那整个事件流动会到此为止,不会发生下面的冒泡阶段。
冒泡阶段(bubble phase)
冒泡阶段的定义如下(w3c):
The event object propagates through the target's ancestors in reverse order, starting with the target's parent and ending with the defaultView.
事件对象会在事件目标的祖先元素里反向传播,由开始的父元素到最后的defaultView(document)。
冒泡阶段发生在最后,这也是我们最为熟悉的一个阶段。在这阶段里事件会从子(分支)到父(主干)逆向传播,看起来像是一个水里的泡泡往上冒。
例子里面,冒泡阶段的click事件会依次在div、body、document上触发:
document 3^
body 2^
div 1 ^ button
"bubbles"
Event下的bubbles属性标明该事件是否为可冒泡的。一旦该值为false,则说明 evnet不可冒泡,那其流动也会在第二阶段“目标阶段”后就终止。
总结
若一个元素(div)是目标元素(button)的祖先,那事件对象会在该元素上触发两次:一次是捕获阶段(1)的,另一次是冒泡阶段(3)的。当事件对象在事件目标元素(button)上触发时,事件流动进入了目标阶段(2)。
- 想监听捕获阶段的事件,可以这样:
element.addEventListener('click', cb, true)
,将第三个参数设置为true。 - 想监听冒泡阶段的事件,可以这样:
element.addEventListener('click', cb,)
,不使用第三个参数或将其设置为false。 - 而上述的任何一种监听方式都可以监听到目标阶段的事件。
最后,你可以配合这个例子来确认一下你的理解。
let divElement = document.querySelector('div')let btnElement = document.querySelector('button') document.body.addEventListener('click', event => { console.log('Body Click in Bubble Phase.') console.log('Event Phase: ' + event.eventPhase) }) document.body.addEventListener('click', event => { console.log('Body Click in Capture Phase.') console.log('Event Phase: ' + event.eventPhase) }, true) divElement.addEventListener('click', event => { console.log('Div Click in Bubble Phase.') console.log('Event Phase: ' + event.eventPhase) }) divElement.addEventListener('click', event => { console.log('Div Click in Capture Phase.') console.log('Event Phase: ' + event.eventPhase) }, true) btnElement.addEventListener('click', event => { console.log('Button Click in Target Phase.') console.log('Event Phase: ' + event.eventPhase) }) btnElement.addEventListener('click', event => { console.log('Button Click in Target Phase.') console.log('Event Phase: ' + event.eventPhase) }, true)
Body Click in Capture Phase.
Event Phase: 1
Div Click in Capture Phase.
Event Phase: 1
Button Click in Target Phase.
Event Phase: 2
Button Click in Target Phase.
Event Phase: 2
Div Click in Bubble Phase. Event Phase: 3 Body Click in Bubble Phase. Event Phase: 3
作者:butterandfly
链接:https://www.jianshu.com/p/382895a4027d
來源:简书
转载于:https://www.cnblogs.com/Yehudic/p/10139752.html
Event flow相关推荐
- WebKit DOM Event (一)
DOM Event 规范 DOM Event 主要定义了三类接口: EventTarget, 所有DOM节点和XMLHttpRequest 都实现EventTarget接口 class EventTa ...
- What is event bubbling and capturing?
What is event bubbling and capturing? 答案1 Event bubbling and capturing are two ways of event propaga ...
- DPDK 报文调度/保序 终极解决方案 Event Dev 简介(硬件加速也很可能是鸿蒙微内核IPC性能的钥匙)...
01 背景介绍 网络报文的分发以及保序一直以来是让人头痛的问题, 为了完整的解释Event Dev的背景,我们可以从两个基本概念的定义开始: 报文分发是指针对网络通信报文的某种特征(例如 5 tupl ...
- netty4.0.x源码分析—bootstrap
Bootstrap的意思就是引导,辅助的意思,在编写服务端或客户端程序时,我们都需要先new一个bootstrap,然后基于这个bootstrap调用函数,添加eventloop和handler,可见 ...
- ActionScript 3.0 Step By Step系列(六):学对象事件模型,从点击按扭开始
事件可以理解为所发生的.ActionScript 能够识别并可响应的事情.许多事件与用户交互有关 . 例如:用户单击按钮,或按键盘上的键 ― 但也有其它类型的事件.例如,如果使用 ActionScri ...
- addeventlistener事件第三个参数 passive_JS DOM 事件流、事件冒泡
当一个HTML元素触发一个事件时,该事件会在元素结点与根结点之间的路径传播.传播按顺序分为三个阶段:捕获阶段.目标阶段.冒泡阶段,这个传播过程就是 DOM 事件流. 事件冒泡就是当一个HTML元素出发 ...
- 监听 html dom 变化,如何监听页面 DOM 变动并高效响应
比来在做 chrome 插件开辟,既然是插件那就不免纰谬现有页面做一些控制,比如事宜监听.调剂构造.对 DOM 元素的增删改查等等.个中有一个需求比较有意思,便整顿一基层便把涉及到的常识点复习一遍. ...
- click事件在什么时候出发_超全的js事件机制amp;事件委托
超全的js事件机制&事件委托,想要理解js事件只需认真看完此篇即可~ 目录结构: 什么是事件机制 事件冒泡事件捕获 DOM事件流事件委托 误区 在同一个对象上注册事件,并不一定按照注册顺序执行 ...
- JavaScript 详说事件机制之冒泡、捕获、传播、委托
DOM事件流(event flow )存在三个阶段:事件捕获阶段.处于目标阶段.事件冒泡阶段. 事件捕获(event capturing):通俗的理解就是,当鼠标点击或者触发dom事件时,浏览器会 ...
最新文章
- SpringBoot介绍
- 案例_文件下载_代码实现
- python错误代码提示手册_腾讯大佬整理了 Python 所有内置异常,Python高手必备的排错手册...
- OPPO Reno 2正式发布:主打4800万变焦四摄 售价2999元
- python中从键盘输入的代码_python如何从键盘获取输入实例
- Python sorted()函数
- pycharm python InvalidVersionSpecError: Invalid version spec: =2.7
- 计算机硬盘扇区修复,w7硬盘坏道修复详细教程
- 车市冷车道 这6款紧凑车苦坐板凳寻伯乐(一)
- VUE 对@click的认识
- Linux 短链timeout状态,Linux命令——timeout
- Python网络编程(OSI Socket)
- moviepy音视频开发:音频合成类AudioArrayClip介绍
- trinity的简介、下载及使用
- 西瓜大作战java 源码_魔改和上线你的合成大西瓜,最全教程!
- PS快捷键大法,初级低配版
- PS Cloud:最适合中小企业的开源云ERP软件
- 温度控制电流c语言编程,利用ATmega16L设计的温度控制系统
- TCP状态转换、半关闭、端口复用
- java是否会员_java20(判断是否为会员)
热门文章
- 区块链以信用为基础,所以目前在中国不可行.
- ASP.NET Core 2.0 MVC 发布部署--------- ASP.NET Core 发布的具体操作
- Spring环境的搭建与测试 (spring2.5.6)
- UVAlive 6131 dp+斜率优化
- [源码学习]调试Razor从哪里开始
- 根本不存在 DIV + CSS 布局这回事
- HDOJ 1030 Delta-wave
- MyEclipse6.0 安装axis2插件, 调用加密的SAP webservice
- 数据分析工具篇——HQL原理及函数逻辑
- 收藏:深度剖析产品经理的「核心竞争力」