事件对象
1.1 > DOM中的事件对象
1.1.1>兼容DOM的浏览器会将一个event对象传入到事件处理程序中。无论指定事件处理程序时使用什么方法(DOM0级或DOM2级),都会传入event对象。
先来看看下面的实例
1 var btn = document.getElementById("myBtn"); 2 btn.onclick = function(event){ 3 alert(event.type); //click 4 }; 5 6 btn.addEventListener("click",function(event){ 7 alert(event.type); //click 8 },false);
1.1.2>在通过html特性指定事件处理程序时,变量event中保存着event对象。请看下面的例子
1 <button onclick="alert(event.type);">点击</button> //click
以这种方式提供event对象,可以让html特性事件处理程序与JavaScript函数执行相同的操作。
event 对象包含于创建它的特定事件有关的属性和方法。触发的事件类型不一样,可用的属性和方法也不一样。
注意其中几个重要的属性即可:
eventPhase 确定事件当前处于事件流那个阶段 1 捕获阶段 2 目标对象上 3 冒泡阶段
currentTarget 代表其事件处理程序当前正在处理事件的那个元素;
target 事件的目标;
stopPropagation() 阻止事件的进一步捕获或冒泡;
preventDefault() 取消事件的默认行为;
type 表示事件类型
在事件处理函数中, this 始终与 currentTarget 相等,而target 则只包含事件的实际目标。
1> 如果直接给实际目标添加事件的话,其三者是相等的
1 var btn = document.getElementById("myBtn"); 2 btn.onclick = function(event){ 3 with(event){ 4 alert(currentTarget === this); 5 alert(target === this); 6 } 7 };
2> 如果事件给添加在父元素(例如 document.body)上的话,是不想等的 如下实例
1 var btn = document.getElementById("myBtn"); 2 document.body.onclick = function(event){ 3 with(event){ 4 alert(currentTarget === this); //true 5 alert(target === this); //false 6 } 7 };
3> 当需要通过一个函数处理多个事件时,可以使用type属性。例如
var btn = document.getElementById("myBtn"); var handler =function(event){ switch(event.type){ case "click": alert("Click"); break; case "mouseover": alert("mouseover"); break; case "mouseout": alert("mouseout"); break; } }; btn.onclick = handler; btn.onmouseover = handler; btn.onmouseout= handler;
4> 当某些时候我们需要阻止事件默认行为,可以使用 preventDefault()方法。例如 常见的链接的默认行为就是在被点击时会导航到其href特性指定的url。
如果想阻止链接导航这一默认行为,那么通过链接的onclick 事件处理程序可以取消它,如下
var link = document.getElementById("myLink"); link.onclick = function(event){ event.preventDefault(); }
注意:只有 cancelable(只读) 属性设置为true 的事件,才可以使用 preventDefault 来取消其默认行为。
5> 当希望停止事件在DOM层次中传播,既取消进一步的事件捕获或冒泡。 例如 当一个按钮事件处理函数中添加stopPropagation()时,可以避免触发注册在docuemnt.body 上的事件处理程序,如下的例子所示
1 var btn = document.getElementById("myBtn"); 2 btn.onclick = function(event){ 3 alert("btn"); // btn 4 event.stopPropagation(); 5 }; 6 document.body.onclick = function(event){ 7 with(event){ 8 alert(currentTarget === this); 9 alert(target === this); 10 } 11 };
6> eventPhase 属性 可以确定事件处于哪个事件流阶段
1 var btn = document.getElementById("myBtn"); 2 btn.onclick = function(event){ 3 alert(event.eventPhase); //2 4 }; 5 document.body.addEventListener("click",function(event){ 6 alert(event.eventPhase);//1 7 },true) 8 document.body.onclick = function(event){ 9 alert(event.eventPhase);//3 10 };
而当 eventPhase 等于 2 时,this、target 和 currentTarget 始终都是相等的。
IE中的事件对象
与访问DOM中event对象不同,要访问IE中的Event对象有几种不同的方式,取决于指定事件处理程序的方法。
1> 在使用DOM0级方法添加事件程序时,event对象作为window对象的一个属性存在。 来看看下面的实例
1 var btn = document.getElementById("myBtn"); 2 btn.onclick = function(){ 3 var event = window.event; 4 alert(event.type); //click 5 };
2> 当事件处理程序通过使用attachEvent()添加的,那么就会有一个event对象作为参数传入事件处理函数中,如下所示
1 var btn = document.getElementById("myBtn"); 2 btn.attachEvent("onclick",function(event){ 3 // var event = window.event; 4 alert(event.type); //click 5 }); 6
3> 如果通过HTML特性指定的时间处理程序,那么可以通过一个名叫event的变量来访问event对象(与dom中事件模型相同)。
<button onclick="alert(event.type);">点击</button> //click
IE的event对象同样也包含与创建它的事件相关的属性和方法。其中很多属性和方法都有对应的或者相关的DOM属性和方法。但所有属性都会包含下表列的属性和方法。
cancelBubble boolean 读/写 默认值为false,但将其设置为true就可以取消事件冒泡(与DOM中的stopPropagation()方法作用相同)
returnValue boolean 读/写 默认值为true,但将其设置为false就可以取消事件的默认行为(与DOM中的preventDefault()方法的作用相同)
srcElement Element 只读 事件的目标对象
type String 只读 被触发的事件类型
因为事件处理程序的作用域是根据指定它的方式来确定的,所以不能认为this会始终等于事件目标。姑 最好使用 event.srcElement 比较保险。 例如
var btn = document.getElementById("myBtn"); btn.onclick = function (){ alert(window.event.srcElement === this); // true this == button }; btn.attachEvent("onclick",function(event){ // var event = window.event; alert(event.srcElement === this); //false this== window });
4 > 利用 returnValue 来实现取消事件默认行为,来看下面的实例 不过与 DOM不同的是,在此没有办法确定事件是否能被取消
1 var myLink = document.getElementById("myLink"); 2 myLink.onclick = function (){ 3 // console.log(this.nodeName); 4 window.event.returnValue = false; 5 };
5 > 利用 canceBubble属性来停止事件冒泡。 由于IE不支持事件捕获,因而只能取消事件冒泡; 但 stopPropagation()可以同时取消事件捕获和冒泡。
1 var btn = document.getElementById("myBtn"); 2 btn.onclick = function (){ 3 alert("Clicked"); //Clicked 4 window.event.cancelBubble = true; 5 }; 6 document.body.attachEvent("onclick",function(event){ 7 alert(event.srcElement === this); 8 });
6> 跨浏览器的事件对象
1 var EventUtil = { 2 3 addHandler:function(element,type,handler){ 4 if(element.addEventListener){ 5 element.addEventListener(type,handler,false); 6 }else if(element.attachEvent){ 7 element.attachEvent("on"+type,handler); 8 }else{ 9 element["on"+type] = handler; 10 } 11 }, 12 removeHandler:function(element,type,handler){ 13 if(element.removeEventListener){ 14 element.removeEventListener(type,handler,false); 15 }else if(element.detachEvent){ 16 element.detachEvent("on"+type,handler); 17 }else{ 18 element["on"+type] = null; 19 } 20 }, 21 getEvent:function(event){ 22 return event?event:window.event; 23 }, 24 getTarget:function(event){ 25 return event.target||event.srcElement; 26 }, 27 preventDefault:function(event){ 28 if(event.preventDefault){ 29 event.preventDefault; 30 }else{ 31 event.returnValue = false; 32 } 33 }, 34 stopPropagation:function(event){ 35 if(event.stopPropagation){ 36 event.stopPropagation(); 37 }else{ 38 event.cancelBubble = true; 39 } 40 } 41 }