1 事件注册
2
3 平常我们绑定事件的时候用dom.onxxxx=function(){}的形式
4 这种方式是给元素的onxxxx属性赋值,只能绑定有一个处理句柄。
5 但很多时候我们需要绑定多个处理句柄到一个事件上,而且还可能要动态的增删某个处理句柄
6 下面的事件注册方式就能解决这个需求。
7
8 先介绍一下四个方法
9
10 复制代码 代码如下:
11
12
13 //IE以外
14 target.addEventListener(type,listener,useCapture)
15 target.removeEventListener(type,listener,useCapture);
16 target :文档节点、document、window 或 XMLHttpRequest。
17 type :字符串,事件名称,不含“on”,比如“click”、“mouseover”、“keydown”等。
18 listener :实现了 EventListener 接口或者是 JavaScript 中的函数。
19 useCapture :是否使用捕捉,一般用 false。
20 //IE
21 target.attachEvent(type, listener);
22 target.detachEvent(type, listener);
23 target :文档节点、document、window 或 XMLHttpRequest。
24 type :字符串,事件名称,含“on”,比如“onclick”、“onmouseover”、“onkeydown”等。
25 listener :实现了 EventListener 接口或者是 JavaScript 中的函数。
26 两者使用的原理:可对执行的优先级不一样,实例讲解如下:
27 ele.attachEvent("onclick",method1);
28 ele.attachEvent("onclick",method2);
29 ele.attachEvent("onclick",method3);
30 执行顺序为method3->method2->method1
31 ele.addEventListener("click",method1,false);
32 ele.addEventListener("click",method2,false);
33 ele.addEventListener("click",method3,false);
34 执行顺序为method1->method2->method3
35 兼容后的方法
36 var func = function(){};
37 //例:addEvent(window,"load",func)
38 function addEvent(elem, type, fn) {
39 if (elem.attachEvent) {
40 elem.attachEvent('on' + type, fn);
41 return;
42 }
43 if (elem.addEventListener) {
44 elem.addEventListener(type, fn, false);
45 }
46 }
47 //例:removeEvent(window,"load",func)
48 function removeEvent(elem, type, fn) {
49 if (elem.detachEvent) {
50 elem.detachEvent('on' + type, fn);
51 return;
52 }
53 if (elem.removeEventListener) {
54 elem.removeEventListener(type, fn, false);
55 }
56 }
57
58
59 获取事件对象和事件源(触发事件的元素)
60
61 复制代码 代码如下:
62
63
64 function eventHandler(e){
65 //获取事件对象
66 e = e || window.event;//IE和Chrome下是window.event FF下是e
67 //获取事件源
68 var target = e.target || e.srcElement;//IE和Chrome下是srcElement FF下是target
69 }
70
71
72 取消事件默认行为(例如点击一个<a>后不跳转页面而是执行一个函数)
73
74 复制代码 代码如下:
75
76
77 function eventHandler(e) {
78 e = e || window.event;
79 // 防止默认行为
80 if (e.preventDefault) {
81 e.preventDefault();//IE以外
82 } else {
83 e.returnValue = false;//IE
84 //注意:这个地方是无法用return false代替的
85 //return false只能取消元素
86 }
87 }
88
89
90 阻止事件冒泡
91
92 复制代码 代码如下:
93
94
95 function myParagraphEventHandler(e) {
96 e = e || window.event;
97 if (e.stopPropagation) {
98 e.stopPropagation();//IE以外
99 } else {
100 e.cancelBubble = true;//IE
101 }
102 }
103
104
105
106 事件委托
107
108 例如,你有一个很多行的大表格,在每个<tr>上绑定点击事件是个非常危险的想法,因为性能是个大问题。流行的做法是使用事件委托。
109
110 事件委托描述的是将事件绑定在容器元素上,然后通过判断点击的target子元素的类型来触发相应的事件。
111 事件委托依赖于事件冒泡,如果事件冒泡到table之前被禁用的话,那以下代码就无法工作了。
112
113
114 复制代码 代码如下:
115
116
117 myTable.onclick = function () {
118 e = e || window.event;
119 var targetNode = e.target || e.srcElement;
120 // 测试如果点击的是TR就触发
121 if (targetNode.nodeName.toLowerCase() === 'tr') {
122 alert('You clicked a table row!');
123 }
124 }
125
126
127
128 事件(Event)知识整理(二)
129
130 事件流
131
132 DOM同时支持两种事件模型:捕获型事件和冒泡型事件
133 并且每当某一事件发生时,都会经过捕获阶段->处理阶段->冒泡阶段(有些浏览器不支持捕获)
134
135 捕获阶段是由上层元素到下层元素的顺序依次。而冒泡阶段则正相反。
136
137 如下图
138
139
140 当事件触发时body会先得到有事件发生的信息,然后依次往下传递,直到到达最详细的元素。这就是事件捕获阶段。
141 还记得事件注册方法ele.addEventListener(type,handler,flag)吧,Flag是一个Boolean值,true表示事件捕捉阶段执行,false表示事件冒泡阶段执行。
142 接着就是事件冒泡阶段。从下往上 依次执行事件处理函数(当然前提是当前元素为该事件注册了事件句柄)。
143 在这个过程中,可以阻止事件的冒泡,即停止向上的传递。
144 阻止冒泡有时是很有必要的,例如
145
146
147 复制代码 代码如下:
148
149
150 <div onclick=funcA()>
151 <button onclick=funcB()>Click</button>
152 </div>
153
154
155
156 本意是如果点击div中按钮以外的位置时执行funcA,点击button时执行funcB。但是实际点击button时就会先后执行funcB,funcA。
157 而如果在button的事件句柄中阻止冒泡的话,div就不会执行事件句柄了。