跨浏览器事件处理和事件委托

封装一个事件处理函数,解决了跨浏览器问题以及多个事件绑定


红皮书13.3.3定义了一个事件处理程序EventUtil

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(element.detachEvent){
element.detachEvent("on"+type,handler);
}else{
element["on"+type]=null;
}
}
};

这个问题要从DOM发展来说了

DOM0级

  • 小写element.onclick=function(){};
  • 简单
  • 跨浏览器
  • 冒泡阶段注册事件处理程序
  • 移除直接element.onclick=null;

DOM2级

  • element.addEventListener(“click”,function(){},false);
    *三个参数:事件名,函数,布尔值。true,捕获阶段调用事件处理程序false,冒泡阶段调用事件处理程序
  • 可以添加多个事件处理程序,依次执行
  • 移除element.removeEventListener(“click”,handler,false);参数要和Add的相同

跨浏览器隔离浏览器差异
为确保大多数浏览器下一致运行,只需要关注冒泡阶段

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
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;
}
}
};

事件委托
13.5.1利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.left{
float: left;
border: 2px solid #868686;
width: 300px;
height: 500px;
margin-right: 5px;
}
.right{
float: left;
width: 500px;
height: 500px;
border: 2px solid #868686;
}
.btn{
text-decoration: none;
display: block;
margin-top: 5px;
color: #000;
background-color: #fff;
border: 1px solid red;
width: 100px;
text-align: center;
}
.active{
color: #fff;
background-color: #000;
}
</style>

</head>
<body>
<div class="left" id="left">
<a href="#" id="btn1" class="btn">element1</a>
<a href="#" id="btn2" class="btn">element2</a>
</div>
<div class="right" id="contentbox">

</div>
<script type="text/javascript">
var btn1=document.getElementById("btn1"),
btn2=document.getElementById("btn2"),
contentBox=document.getElementById("contentbox"),
_div=document.getElementById("left");
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;
}
}
};
EventUtil.addHandler(_div,"click",function(event){
event=EventUtil.getEvent(event);
var target=EventUtil.getTarget(event);
switch(target.id){
case "btn1":
{
btn1.className="btn active";
btn2.className="btn";
contentBox.innerHTML=btn1.innerHTML;
};
break;
case "btn2":
{
btn2.className="btn active";
btn1.className="btn";
contentBox.innerHTML=btn2.innerHTML;
};
break;
}
});
</script>

</body>
</html>

事件委托比事件绑定优点:占内存小,耗时少