- 事件流
事件流描述的是从页面中接收事件的顺序,ie的事件流是事件冒泡流,而Netscape Communicator的事件流是事件捕获流。
- 事件冒泡
Ie的事件流叫做事件冒泡,即事件开始时有最具体的元素接收,然后逐级向上传播到较为不具体的节点。
- 事件捕获
事件捕获的思想是不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。
- DOM事件流
DOM2级事件规定事件流包括三个阶段:事件捕获,处于目标阶段和事件冒泡节点,首先发生的是事件捕获,为截获事件提供了机会,然后是实际的目标接收到事件,最后一个阶段是冒泡节点,可以在这个阶段对事件做出响应。
- HTML事件处理程序
<input type=”button” value=”click me” onclick=”alert(‘clicked’)”/>
- DOM0级事件处程序
var btn=documenr.getElementById(“myBtn”); btn.onclick=function(){ alert(“clicked”); };
- DOM2级事件处理程序
Dom2级事件定义了两个方法addEventListener()和removeEventListener(),接受3个参数:要处理的事件名,作为事件处理程序的函数和一个布尔值如果是true,表示在捕获阶段调试事件处理程序,如果是false,表示在冒泡阶段调用事件处理程序。例如:
var btn=document.getElementById(“myBtn”); btn.addEventListener(“click”,function(){ alert(this.id); },false);
上面的代码为一个按钮添加了onclick事件处理程序,而且该事件会在冒泡阶段被触发。与dom0级方法一样,这里添加的事件处理程序也是在其依附的元素的作用域中运行,例如:
var btn=document.getElementById(“myBtn”); btn.addEventListener(“click”,function(){ alert(this.id); },false) btn.addEventListener(“click”,function(){ alert(“Hello word!”); },false);
移除例子:
var btn=docunment.getElementById(“myBtn”); var handler=function(){ alert(this.id); }; btn.addEventListener(“click”,handler.false); btn.removeEventListener(“click”,handler,false);
大多数情况下,都是将事件处理程序添加到事件流的冒泡阶段,这样可以最大限度的兼容各种浏览器,最好只在需要在事件到达目标之前截获它的时候将事件处理程序添加到捕获阶段,如果不是特别需要,我们不建议在事件捕获阶段注册事件处理程序。
- IE事件处理程序
Ie实现了与dom中类似的两个方法,attachEvent()和detachEvent(),这两个方法接受相同的两个参数:事件处理程序名称与时间处理程序函数。由于ie8以前的版本只支持事件冒泡,所以通过attachEvent()添加的事件处理程序都会被添加到冒泡阶段例如:
var btn=document.getElementById(“myBtn”); btn.attachEvent(“onclick”,function(){ alert(“clicked”); })
注意,attachEvent的第一个参数是onclick,而非dom的addeventlistener方法中的是click。
在ie中使用attachevent与使用DOM0级方法的主要区别在于事件处理程序的作用域,在使用DOM0级方法的情况下,事件处理程序会在其所属元素的作用域内运行,在使用attachevent方法的情况下,this指向window。
- 跨浏览器的事件处理程序
代码如下:
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; } } }
- DOM中的事件对象
兼容DOM的浏览器会将一个event地下传入到事件处理程序中,无论指定事件处理程序时使用什么方法,都会传入event对象,例如:
var btn=document.getElementById(“myBtn”); btn.onclick=function(event){ alert(event.type); }; btn.addEventListenner(“click”,function(event){ alert(event.type) },false);
在事件处理程序内部,对象this始终等于currentTarget的值,而target则只包含事件的实际目标,如果事件处理程序存在于按钮的父节点中,那么这些值是不同的,例如:
doucument.body.onclick=function(event){ alert(event,currentTarget===document.body);//true alert(this===doucument.body);//true alert(event.target===document.getElementById(“myBtn”));//true }
在需要通过一个函数处理多个事件时,可以使用type属性,例如
var btn=document.getElementById(“myBtn”); var handler=function(event){ switch(event.type){ case ”click”: alert(“Clicked”); breadk; case “mouseover”: event.target.style.backgroundColor=”red”; case “mouseout”: event.target.style.backgroundColor=””; } }; btn.onclick=handler; btn.onmouseover=handler; btn.onmouseout=handler;
要阻止特定事件的默认行为,可以使用preventDefault()方法,例如,链接的默认行为就是在被单击时会导航到其href特性指定的URL,如果你想阻止链接导航这一默认行为,那么通过链接onclick事件处理程序可以取消它。
var link=document.getElementById(“myLink”); link.onclick=function(event){ event.preventDefault(); };
只有cancelable属性设置为true的事件,才可以使用preventDefault()来取消默认行为。stopPropagation方法用于立即停止事件在DOM层次中的传播,即取消进一步的事件捕获或冒泡,例如:
var btn=document.getElementById(“myBtn”); btn.onclick=function(){ alert(“Clicked”); event.stopPropagation(); }; Document.body.onclick=function(event){ alert(“Body clicked”); };
对象的eventPhase属性,可以用来确定事件当前正位于事件流的哪个阶段,捕获阶段值为1,目标对象上值为2,冒泡阶段值为3:
var btn=docunment.getElementById(“myBtn”); btn.onclick=function(event){ alert(event.eventPhase);//2 }; document.body.addEventListener(“click”,function(event){ alert(event.eventPhase);//1 }); document.body.onclick=function(event){ alert(event.eventPhase);//3 }
- Ie中的事件对象
IE中的event对象有几种不同的方式,取决于指定事件处理的方法,在DOM0级方法添加事件处理程序,event对象作为window对象的一个属性存在,例如:
var btn=document.getElementById(“myBtn”); btn.onclick=function(){ var event=window.event; alert(event.type); };
如果事件处理程序是使用attachEvent添加的,那么就会有一个event对象作为参数被传入事件处理程序函数中。例如:
var btn=document.getElementById(“myBtn”); btn.attachEvent(“onclick”,function(event){ alert(event.type); });
因为事件处理程序的作用域是根据指定它的方式来确定的,所以不能认为this会始终等于事件目标,因此还是使用event.srcElement比较保险。
var btn=document.getElementById(“myBtn”); btn.onclick=function(){ alert(window.event.srcElement===this);//true } btn.attachEvent(“onclick”,function(event)){ alert(event.srcElement===this);//false }