@@ -47,6 +47,77 @@ DOM 事件流为 DOM 事件的处理及执行的过程。下面以一个`<a>`元
47472 . [ 红绿实线] Target Phase(事件触发过程)当事件被捕获之后就开始执行事件绑定的代码
48483 . [ 绿虚线] Bubble Phase(冒泡过程)当事件代码执行完毕后,浏览器会从触发事件元素的父节点开始一直冒泡到window元素(** 即元素的祖先元素也会触发这个元素所触发的事件** )
4949
50+ ** 关于捕获过程的补充**
51+
52+ 如果有一个支持三个阶段的事件,它一定在触发时遵循下面的顺序:
53+
54+ ```
55+ Capture -> Target -> Bubbling
56+ ```
57+
58+ ![ ] ( ../img/E/event-phases.png )
59+
60+ 使用下面的代码来举例:
61+
62+ ``` JavaScript
63+ // 添加Capture阶段事件
64+ docuemnt .addEventListener (' click' ,function (){
65+ alert (' capture:' + 1 );
66+ },true );
67+ tableNode .addEventListener (' click' ,function (){
68+ alert (' capture:' + 2 );
69+ },true );
70+ tdNode .addEventListener (' click' ,function (){
71+ alert (' capture:' + 3 );
72+ },true );
73+
74+ // 添加Bubbling阶段事件
75+ docuemnt .addEventListener (' click' ,function (){
76+ alert (' bubble:' + 1 );
77+ });
78+ tableNode .addEventListener (' click' ,function (){
79+ alert (' bubble:' + 2 );
80+ });
81+ tdNode .addEventListener (' click' ,function (){
82+ alert (' bubble:' + 3 );
83+ });
84+ ```
85+
86+ 输出结果为:
87+
88+ ```
89+ capture:1
90+ capture:2
91+ capture:3
92+ bubble:3
93+ bubble:2
94+ bubble:1
95+ ```
96+
97+ ![ ] ( ../img/E/event-apply.png )
98+
99+ ``` javascript
100+ // 对document添加了三个bubbling阶段的事件
101+ document .addEventListener (' click' ,function (){
102+ alert (1 );
103+ });
104+ document .addEventListener (' click' ,function (){
105+ alert (2 );
106+ });
107+ document .addEventListener (' click' ,function (){
108+ alert (3 );
109+ });
110+ ```
111+
112+ 如上面的代码所示,其为同一节点添加了同一阶段的多个事件,那执行顺序如何呢?
113+ 早期并没有规范定义,DOM 3 中规范已经明确规定
114+ 同一节点同一阶段的事件应按照注册函数的顺序执行。
115+
116+ > 在实际项目过程中,某些情况下比如若干的组件或者模块都需要监听某个节点的某个事件,但是组件或者模块的生成(即添加事件的时机)是不一定保证顺序的,所以这个情况下如果某个组件对这个节点的这个事件的优先级特别高(需要保证必须先触发这个组件里的这个事件)而这个平台又支持这个阶段事件的话可以添加capture阶段事件,用三阶段的顺序来保证,比如移动平台模拟手势的实现会添加document上touchXXX的capture阶段事件,以优先识别手势操作
117+ > 当然实践过程中考虑到不同浏览器对三阶段支持的情况的差异,大部分情况下都采用的是bubbling阶段的事件
118+ >
119+ > —— 蔡剑飞 网易前端工程师
120+
50121NOTE:低版本 IE 中并未实现捕获过程。也不是所有事件均存在这三个完整的过程(例如 ` load ` 没有冒泡事件)
51122
52123NOTE+:在这三个阶段中无论将** 事件捕获** 和** 事件处理** 注册到任意一个父或祖父节点上都会被触发事件。
@@ -433,4 +504,4 @@ elem.addEventListener('click', function(event) {
433504
434505** 缺点**
435506
436- - 事件管理的逻辑变的复杂(因为冒泡机制)
507+ - 事件管理的逻辑变的复杂(因为冒泡机制)
0 commit comments