JavaScipt事件(2)

跨浏览器的事件处理程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var 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;
}
},
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;
}
},
}

顺序

  1. DOM2级方法:false表示在冒泡阶段调用
  2. IE8下的方法执行顺序
  3. DOM0级最不提倡的方法(现代浏览器不执行)

缺点:
不考虑所有浏览器的问题:IE中的作用域,多次使用时事件调用的顺序,DOM0级只支持一个事件处理程序

事件对象

DOM中的事件对象

  • 使用DOM0级或者DOM2级方法,浏览器都会传入一个event对象到事件处理程序中HTML DOM Event 对象
  • 在事件处理程序内部,this始终等于currentTarget的值,而target只包含事件的实际目标。如果事件处理程序在按钮的父节点中,target是实际处理的目标,this和currentTarget是父节点。
  • 在需要通过一个函数处理多个事件时,利用type属性来区分,使用swtich。
  • 要阻止特定事件的默认行为,使用preventDefault()。比如链接的默认行为
    是单击时调到Href指定的链接。(cancelable为true的事件才能使用)
  • 要阻止事件在DOM中的传播,即取消进一步的事件捕获或冒泡使用stopPropagation()。
  • 要确定事件当前处于事件流的哪个阶段,使用eventPhase属性:1代表事件捕获阶段,2代表事件处理程序处于目标对象上(实际上这是在冒泡阶段),3是指在冒泡阶段调用的事件处理程序。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    var btn = document.getElementById('mybtn');
    btn.onclick = function (event) {
    alert(event.eventPhase);//2
    }
    document.body.addEventListener("click", function (event) {
    alert(event.eventPhase);//1
    },true);
    document.body.onclick = function (event) {
    alert(event.eventPhase);//3
    }

弹出顺序为:1 2 3;
首先是body中捕获阶段会弹出1;接着是处于目标状态上的事件处理程序;最后是冒泡阶段,在body中,显示3。

IE中的事件对象

访问IE中的event对象有几种方式,取决于指定事件处理程序的方法。
DOM0级方法添加事件处理程序时,event对象作为window对象的一个属性存在。即event = window.event
IE事件处理方法添加事件处理程序时,就是直接的event对象传入函数中。
HTML特性指定的事件处理程序能直接使用event的变量访问event对象HTML DOM Event 对象
之前说过,this在事件处理程序中的指向随着方法的不同而不同,因此使用event.srcElement比较保险。
此外,returnValue属性相当于DOM中的preventDefault()方法,设置为false阻止默认行为。而cancelBubble属性与stopPropagation()方法作用相同,阻止事件冒泡。这两种属性用在window.event中。

##跨浏览器的事件对象

1
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
40
41
42
43
44
45
var 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;
}
}
};

都很好理解,不详细说了。

参考书目:《JavaScript高级程序设计》

分享到