事件

事件流

  • 事件冒泡

    事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)
  • 事件捕获

    不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件
    事件捕获用意在于在事件到达预定目标之前捕获它
  • DOM事件流

    (事件流描述的是从页面中接收事件的顺序)
  1. 事件捕获阶段(从document开始)
  2. 处于目标阶段
  3. 事件冒泡阶段

事件处理程序

HTMl事件处理程序

某个元素支持的每种事件,都可以使用一个与相应事件处理程序同名的HTML特性来指定

  • 特性的值

可以是能够执行的js代码

1
<input type="button" value="按钮" onclick="alert('Clicked')"/>

也可以调用在页面其他地方定义的脚本

1
2
3
4
5
6
<input id="btn" value="click me" onclick="showMessage()" />
<script type="text/javascript">
  function showMessage(){
   alert("clicked");
}
</script>
  • 扩展作用域
1
2
3
4
5
6
7
8
function(){
with(document){
eith(this){
//元素属性值
}
}
} 在这个函数内部,可以像访问局部变量一样访问document
及该元素本身的成员

DOM0级事件处理程序(主要)

通过JavaScript指定处理程序的传统方式,将一个函数赋值给一个事件处理程序属性。每个元素(包括document和window)都有自己的事件处理程序属性
以这种方式添加的事件处理程序会在事件流的冒泡阶段被处理

1
2
3
4
5
6
7
8
9
var btn = document.getElementById("btn");
btn.onclick = function(){
alert("Clicked"); //指定事件处理程序
};
btn.onclick=function(){
alert(this.id);//btn //其作用域为元素的作用域
}
//想要取消事件处理程序的话,只需将事件处理程序属性设为null即可
btn.onclick = null;

DOM2级事件处理程序

用于处理指定和删除事件处理程序的操作:
addEventListener()和removeEventListener()

1
2
3
4
5
6
7
8
//指定事件处理程序 
btn.addEventListener("click",fucntion(){
alert("clicked");},false);
//取消事件处理程序
btn.removeEventListener("click",function(){
alert("clicked");},false);//无效
//指定和取消的参数必须完全相同才有效
//而匿名函数是两个不同的函数,所以无效

为了能够取消,最好函数采用函数表达式

1
2
3
4
5
6
7
var handler = function(){
alert("clicked");
};
//添加事件处理程序
btn.addEventListener("click",handler,false);
//取消事件处理程序
btn.removeEventListener("click",handler,false);//有效

IE事件处理程序

用于处理指定和删除事件处理程序的操作:
attachEvent()和detachEvent()

IE事件处理程序与DOM事件处理程序的最大区别:
DOM0/2级事件处理程序的作用域是元素作用域;
而IE事件处理程序是全局作用域,即this等于widow

1
2
3
4
5
6
7
8
9
var handler = function(){
alert("clicked");
};
//指定事件处理程序
btn.attachEvent("onclick",handler);
//取消事件处理程序
btn.detachEvent("onclick",handler);
//取消参数必须与添加完全相同
所以事件处理程序函数(同DOM2级事件中的分析一样)不要是匿名函数。

跨浏览器的事件处理程序

用于处理指定和删除事件处理程序的操作:
addHandler()和removeHandler()
这两个方法属于一个名叫EventUtil的对象

1
2
3
4
5
6
7
var handler = function(){
alert("Clicked");
};
//指定事件处理程序
EventUtil.addHandler(btn,"click",handler);
//移除事件处理程序
EventUtil.removeHandler(btn,"click",handler);

事件对象

在触发DOM上的某个事件时,会产生一个事件对象event。这个对象中包含着所有与事件有关的信息。包括导致事件的元素,事件的类型以及其他与特定事件相关的信息
所有浏览器都支持event对象,event对象会传入DOM0级,DOM2级,HTML指定的事件处理程序中,但支持的方式不同,所以也会涉及跨浏览器的部分

DOM中的事件对象

相关属性方法详见书355

两个有点难区分的属性:

  • currentTarget:this对象始终是指向它的值,为其事件处理程序当前正在处理事件的那个元素
  • target:只包含事件的目标

IE中的事件对象

相关属性方法详见书359

跨浏览器的事件对象

对前面介绍到的EventUtil对象加以增强
添加如下方法 ,写一个通用的事件侦听函数即可

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
听说面试会问到,这样写就可以了
var EventUtil={
getEvent:function(event){
return event||window.event;
},
getTarget:function(event){
return event.target||event.srcElement;
},
preventDefault:function(){
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue=false;
}
},
stopPropagation:function(){
if(event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble=true;
}
},
addHandler:function(element,type,handler){
if(element.addEventListener){
element.addEventListener(type,handler,false);
}else if(element.attachEvent){
element["e"+type]=function(){
handler.call(element)
}
element.attachEvent("on"+type,element["e"+type]);
}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,element["e"+type]);
element["e"+type]=null;
}else{
element["on"+type]=null;
}
}

};

事件类型

好像没什么必要一一列出来了,详见书中362

内存和性能

事件委托

  • 利用冒泡的原理,把事件加到父级上,触发执行效果
  • 通俗的讲,就是这个事件本来是加在某些元素上的,然而你却加到别人身上来做,完成这个事件
  • 使用事件委托,只需在DOM树中尽量最高的层次上添加一个事件处理程序

移除事件处理程序

  • 从文档中移除带有事件处理程序的元素时
  • 卸载页面时

模拟事件

DOM中的事件模拟

  • 调用document.createEvent()方法创建event对象
  • 初始化对象,为对象添加相关信息
  • 调用dispatchEvent()方法触发事件

IE中的事件模拟

  • 调用document.createEventObject()方法创建event对象
  • 初始化对象,为对象添加相关信息
  • 调用fireEvent()方法触发事件
-------------本文结束 感谢您的阅读-------------