事件触发过程
在前端开发中,经常会遇到事件监听,很多人对事件捕获及事件冒泡不置可否,以下是我对事件模型的一些看法,简单来说就是从外向内捕捉,然后到目标阶段后依次向上冒泡,详情请自行W3C。
图片引用自W3C
1、捕获阶段:在事件对象到达事件目标之前,事件对象必须从window经过目标的祖先节点传播到事件目标。 这个阶段被我们称之为捕获阶段。在这个阶段注册的事件监听器在事件到达其目标前必须先处理事件。
2、目标阶段:事件对象到达其事件目标。 这个阶段被我们称为目标阶段。一旦事件对象到达事件目标,该阶段的事件监听器就要对它进行处理。如果一个事件对象类型被标志为不能冒泡。那么对应的事件对象在到达此阶段时就会终止传播。
3、冒泡阶段:事件对象以一个与捕获阶段相反的方向从事件目标传播经过其祖先节点传播到window。这个阶段被称之为冒泡阶段。在此阶段注册的事件监听器会对相应的冒泡事件进行处理。
跨浏览器EventUtil
以下是js大神Nicholas Zakas写的Professional JavaScript for Web Developers中的Cross Browser Event Utility
查看Hugh Dai Gist1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40var EventUtil = {
addHandler: function( element, type, handler ) {
if ( element.addEventListener ) {
element.addEventListener ( type, handler, false );
} else if ( element.attachEvent ) {
element.attachEvent ( "on" + type, handler );
} else {
element["on" + type] = handler;
}
},
getEvent: function ( event ) {
return event ? event : window.event;
},
getTarget: function ( event ) {
return event.target || event.srcElement;
},
preventDefault: function ( event ) {
if ( event.preventDefault ) {
event.preventDefault();
} else {
event.returnValue = false;
}
},
removeHandler: function( element, type, handler ) {
if ( element.removeEventListener ) {
element.removeEventListener ( type, handler, false );
} else if ( element.detachEvent ) {
element.detachEvent ( "on" + type, handler );
} else {
element["on" + type] = null;
}
},
stopPropagation: function ( event ) {
if ( event.stopPropagation ) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
}
};
Demo
这里修改一下大神Wilson Page的一个demo,更形象的描述事件流模型。