事件流
事件流
描述的是页面接收事件的顺序.IE的事件流是冒泡流,而 Netscape Communicator的事件流是事件捕获流.
事件冒泡
是指事件开始时由最具体的元素,然后向上传播到较为不具体的节点.所有现代浏览器都支持事件冒泡,IE9,Firefox,chrome,safari则将事件一直冒泡到window对象.
事件捕获
是不太具体的节点应该更早接收到事件,而具体的节点应该最后接收到事件.
DOM事件流
事件处理程序
HTML事件处理程序
以on
+事件名(例如onclick
)作为事件目标的属性,属性值为事件处理程序,在html中定义的事件处理程序可以包含要执行的具体动作,也可以调用页面其他地方定义的脚本.
function showMessage(){ alert("Hello world!");}
DOM0级事件处理程序
DOM0级事件处理程序是在js中处理的,它的优势是简单,目前所有浏览器支持良好,并且不会与html代码产生耦合.
var btn = document.getElementById('btn'); btn.onclick = function(){ alert('clicked me!'); };
这里是把事件处理程序赋值给了DOM对象的属性,这个属性的构成是on
+事件名,比如onclick
`onblur`onload
.
DOM2级事件处理程序
DOM2级事件定义了两个方法addEventListener
removeEventListener
,这两个方法都接收三个参数.第一个参数代表事件类型;第二个参数代表事件处理程序;第三个参数是指在冒泡阶段还是捕获阶段处理事件处理程序,如果为true代表捕获阶段处理,如果是false代表冒泡阶段处理.
var btn = document.getElementById('btn'); //事件处理程序 function handler(){ alert('click!'); } //注册事件处理程序 addEventListener('click',handler,false); //注销事件处理程序 removeEventListener('click',handler,false);
注:添加匿名事件处理程序无法被注销
IE事件处理程序
IE8及以下浏览器不支持DOM2级事件处理程序,但也自己定义了attachEvent
`detachEvent`两个方法,这两个方法只接受两个参数,因为IE8及以下版本不支持事件捕获,所以没有第三个参数.
var btn = document.getElementByID("btn"); //事件处理程序 function handler(){ alert('click!'); } //注册事件处理程序 attachEvent('click',handler,false); //注销事件处理程序 detachEvent('click',handler,false);
跨浏览器的事件处理程序
综合以上几种事件处理程序,我们封装出了一个跨浏览器的事件处理程序对象.
var EventUtil ={ //注册事件处理程序 addEventHandler: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; } }, //注销事件处理程序 removeEventHandler: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; } } }; var btn = document.getElementById('btn'), handler=function(event){ alert(this.value); }; EventUtil.addEventHandler(btn,'click',handler);
事件对象
在触发DOM的某个事件时,会产生一个事件对象,这个对象包含着所有与事件相关的信息。包括导致事件的元素,事件的类型,以及其他与特定事件相关的信息.例如鼠标操作导致的事件对象中,包含鼠标位置的信息,键盘定义的事件中包含按下键相关的信息.所有浏览器支持event对象,但支持方式不同.
DOM中的事件对象
兼容DOM的浏览器会将一个event对象传入到事件处理程序中.DOM0和DOM2都会传入event. html事件处理程序也有event对象.
var btn = document.getElementById("btn"); btn.onclick = function(event){ alert(event.type); } btn.addEventHandler('click',function(event){ alert(event.type); },false);
触发的事件类型不一样,可用的属性和方法也不一样.不过所有事件的event对象都有公共成员,这里列出几个常用的属性和方法.
属性
currentTarget
指向某个元素,事件处理程序发生在此元素上target
事件的目标type
事件类型eventPhase
事件所处阶段事件
preventDefault()
取消事件的默认行为stopPropagation()
取消事件的进一步冒泡或捕获在事件处理程序内部,对象this始终等于currentTarget的值.而target则只包含事件的实际目标.
IE中的事件对象
使用DOM0级事件处理程序时,event对象作为window对象的一个属性存在;
使用attachEvent()事件处理程序时,event对象作为参数传入.跨浏览器的事件对象
var EventUtil = { //添加事件 addEventHandler: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; } }, //移除事件 removeEventHandler: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; } }, //获取事件对象 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; } }, //阻止事件冒泡 stopPropagation:function(event){ if(event.stopPropagation) { event.stopPropagation(); } else{ event.cancelBubble=true; } }};
使用以上定义的EventUtil
对象,可以在所有浏览器中进行进行事件的添加
,移除
,获取事件对象
,获取事件目标
,阻止事件冒泡
,阻止事件默认行为
.