什么是事件流
javaScript与HTML之间的交互是通过事件实现的。事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间。可以使用侦听器(或处理程序)来预订事件,以便事件发生时执行相应的代码。这种模型使用了我们的观察者模式,支持页面的行为(JS代码)与页面的外观(HTML,CSS)之间的松散耦合。当浏览器发展到第四代时,IE和Netscape开发团队使用了两个完全相反的事件流概念,IE的事件流是事件冒泡流,而Netscape的事件是事件捕获流。
事件冒泡
所谓事件冒泡,就是指该事件开始由最具体的元素接收,然后逐级向上传播到较为不具体的节点;
<html>
<head>
<title>createElement() Example</title>
</head>
<body >
<div id="div1">
Click
</div>
</body>
</html>
如果你点击了页面的div元素,那么这个click事件会按照如下顺序传播:
1.div
2.body
3.html
4.document
这个click会从我们点击的元素div上发生,然后再沿着dom树向上传播,在每一级节点上都会发生,直到传播到document对象;
事件捕获
事件捕获的思想是从不太具体的节点开始接收事件,而最具体的节点应该最后接收到事件。事件捕获的用意在于事件到达预定目标之前捕获它。如果仍然以前面的HTML页面作为演示事件捕获的例子,那么单击DIV元素就会以下顺序出发click事件。
1.document
2.html
3.body
4.div
在事件捕获过程中,document对象首先接收到click事件,然后事件沿着DOM树依次向下,一直传播到事件的实际目标,即div元素。
DOM事件流
规定的事件流包括三个阶段:事件捕获阶段,处于目标阶段和事件冒泡阶段首先是事件捕获,为截获事件提供了机会。然后是实际的目标接到事件。最后一个阶段是冒泡阶段,可以在这个阶段对事件做出响应。
在DOM事件流中,实际的目标div在捕获阶段不会接收到事件,比如说我们点击了div事件,那么在铺货阶段的时候会从范围最大的开始捕获从document到html到body这个时候快到div的时候,捕获事件就停止了,然后进行下一个阶段。处于目标阶段,于是事件在div上发生,并在事件处理中被看成冒泡阶段的一部分,最后冒泡事件发生,又传播回文档。
事件处理程序
事件是指用户或浏览器的某种动作,比如click,load都是事件的名字,而响应某个事件的函数就叫做事件处理程序,事件处理程序都是以on开头的(至少在JS里面是);
指定事件处理程序会创建一个封装着元素属性值的函数。这个函数中有一个局部变量event,也就是事件对象。
<input type="button" value="Click" οnclick="alert(event.type)">
通过event变量,可以直接访问事件对象,可以不用自己定义它,也不用从函数的列表中读取。在这个函数内部,this值等于事件的目标元素。
<input type="button" value="Click" οnclick="alert(this.type)">
扩展作用域
在这个函数内部,可以像f访问局部变量一样访问document及该元素本身的成员。这个函数使用with扩展作用域
<script>
function(){
with(document){
with(this){
}
}
}
</script>
这样我们可以直接访问该目标元素
<input type="button" value="Click" οnclick="alert(type)">
经测试发现很多浏览器已经自动的做了扩展作用域,也就是说你不加上那段js代码,这样直接访问也是可以的;
事件句柄和事件接听器
事件句柄
事件句柄(又称事件处理函数,DOM称之为事件监听函数),用于响应某个事件而调用的函数称为事件处理函数
。每一个事件均对应一个事件句柄,在程序执行时,将相应的函数或语句指定给事件句柄,则在该事件发生时,浏览器便执行指定的函数或语句,从而实现网页内容与用户操作的交互。当浏览器检测到某事件发生时,便查找该事件对应的事件句柄有没有被赋值,如果有,则执行该事件句柄。
我们认为响应点击事件的函数是onclick事件处理函数。以前,事件处理函数有两种分配方式:在JavaScript中或者在HTML中。
<html>
<head>
<title>createElement() Example</title>
</head>
<body >
<div id="div1">
<input type="button" value="Click" id="mybt">
</div>
</body>
<script>
var btn=document.getElementById("mybt");
btn.οnclick=function(){
alert("点击事件");
}
</script>
</html>
如果在JavaScript 中分配事件处理函数, 则需要首先获得要处理的对象的一引用,然后将函数赋值给对应的事件处理函数属性。从我们看到的例子中,我们发现使用事件句柄很容易,不过事件处理函数名称必须是小写的,还有就是只有在元素载入完成之后才能将事件句柄赋给元素,不然会有异常。这种JavaScript 代码和通过HTML的style属性直接将CSS属性赋给元素类似。这样会代码看起来一团糟,也违背了将实现动态行为的代码与显示文档静态内容的代码相分离的原则。
DOM2级事件处理程序
上面的处理方式我们称之为DOM0级事件处理程序,后来又诞生了DOM2级事件处理程序,它定义了两个方法,用于处理指定和删除事件处理程序的操作,addEventListener和removeEventListener()。
所有DOM节点都包含这两个方法,并且它们都接收处理的事件名,作为事件处理程序的函数和一个布尔值。true表示在捕获阶段调用事件处理程序;false则表示在冒泡阶段调用事件处理程序。
<script>
var btn=document.getElementById("mybt");
btn.addEventListener("click",function(){
alert(this.id);
},false);
</script>
不知道为撒我的IE居然不支持这种方式,其他浏览器是可以的,看来IE确实很low;由于我上面添加的是匿名函数(也就是没有传入函数的名称)所以我无法通过removeEventlistener()去删除掉这个事件。。不过IE有自己的事件处理程序。它们是attachEvent()和上面的addEventListener()类似;还有个detachEvent移除事件处理;