js的事件委托(事件处理)
----事件流
事件冒泡:事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点。所有现在浏览器都支持,只是具体实现有所差异。IE9/firefox/chrome/safari会将事件一直冒泡到window对象。
事件捕获:在事件到达预定目标之前,不太具体的节点先接收到事件,最具体的节点最后接收。IE9/firefox/chrome/safari/opera支持。
‘DOM2级事件’规定事件流包含三个阶段:捕获,目标,冒泡。
---事件处理程序
HTML事件处理程序:要注意未转义字符"代替双引号。绑定的事件执行时会扩展作用域,有权访问到全局作用域中的任何代码,利于传参啊。缺点:时差问题,如果想在html一出现就触发函数,但此时script脚本还没有加载完;如此扩展作用域,在不同的浏览器里会导致不同的问题,比如访问成员出错;html和javascript紧密耦合。
DOM0级事件处理程序:先在script中取得元素的引用,然后再将一个函数赋值给onclick事件处理程序。方法是绑定对象的,作用域是对象而不是全局。解决了HTML事件的三个缺点,然而,同样有两个缺点:不能给同一个元素绑定多个事件,会覆盖;不能控制元素的事件流。
<button id="button">点我</button> <script> var button=document.getElementById("button"); button.onclick=function(){ alert("clicked"); } </script> //删除事件 button.onclick=null;
DOM2级事件处理程序:addEventListener() ---添加事件侦听器;removeEventListener() ---删除侦听器;(type,func,boolean),false默认冒泡。一般不使用true,因为低版本的IE不支持捕获阶段。
优点:可以为同一个元素添加两个或更多的事件。事件根据顺序依次触发。且this同样指向当前元素,故函数在元素的作用域中执行。
<button id="button">点我</button> <script> var button=document.getElementById("button"); function handler(){ alert(this.id); } button.addEventListener("click",handler,false); button.removeEventListener("click",handler,false); </script>
然而IE总是特立独行的~~
IE事件处理程序:attachEvent(),detachEvent(onclick/onmouseover,handler),不同于DOM0和DOM2中this指向元素,IE中的this指向window;可以使用attachEvent()来给同一个元素添加多个事件处理程序。但是与DOM2不同,事件触发的顺序不是添加的顺序而是添加顺序的相反顺序;与DOM2同样地,通过attachEvent()添加的事件处理程序必须通过detachEvent()方法移除,不能使用匿名函数;支持IE事件处理程序的浏览器不只有IE浏览器,还有Opera浏览器。
-------完结-------
跨浏览器的事件处理的实现:
var EventUtil={ addHandler:function(element,type,handler){ if(element.addEventListener){ element.addEventListener(type,handler,false);//注意:这里默认使用了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);//注意:这里默认使用了false(冒泡) }else if(element.detachEvent){ element.detachEvent("on"+type,handler); }else{ element["on"+type]=null; } }, getEvent:function(event){ return event?event:window.event; }, getTarget:function(){ return event.target||event.srcElement } };
对‘事件处理程序过多’的问题的解决方案就是事件委托。利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
作用: