DOM和IE中的event对象不同,IE中的event对象的全部信息和方法DOM对象中都有,只不过实现方式不一样。不过,这种对应关系让实现两种事件模型之间的映射非常容易。可以对上一篇文章介绍的EventUtil对象加以增强,添加如下方法以求同存异。
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 13 getEvent:function (event) { 14 return event ? event : window.event; 15 }, 16 17 getTarget:function (event) { 18 return event.target || event.srcElement; 19 }, 20 21 preventDefault:function (event) { 22 if (event.preventDefault) { 23 event.preventDefault(); 24 } else { 25 event.returnValue = false; 26 } 27 }, 28 29 removeHandler: function(element, type, handler) { 30 if (element.removeEventListener) { 31 element.removeEventListener(type, handler, false); 32 } else if (element.detachEvent) { 33 element.detachEvent("on" + type, handler); 34 } else { 35 element["on" + type] = null; 36 } 37 }, 38 39 stopPropagation:function (event) { 40 if (event.stopPropagation) { 41 event.stopPropagation(); 42 } else { 43 event.cancelBubble = true; 44 } 45 } 46 };
我们为EventUtil添加了4个新方法。第一个是getEvent(),它返回对event对象的引用。考虑到IE中事件对象的位置不同,可以使用这个方法来取得event对象,而不必担心指定事件处理程序的方式。在使用这个方法时,必须假设有一个事件对象传入到事件处理程序中,而且要把该变量传给这个方法,如下所示:
1 btn.onclick = function(event){ 2 event = EventUtil.getEvent(event); 3 };
在兼容DOM的浏览器中,evnet变量只是简单地传入和返回。而在IE中,event参数是未定义的(undefined),因此就会返回window.event。
第二个方法是getTarget(),它返回事件的目标。在这个方法内部,会检测event对象的target属性,如果存在则返回该属性的值;否则,返回srcElement属性的值。可以像下面这样使用这个方法:
1 btn.onclick = function(event) { 2 event = EventUtil.getEvent(event); 3 var target = EventUtil.getTarget(event); 4 };
第三个方法是preventDefault(),用于取消事件的默认行为。在传入event对象后,这个方法会检查是否存在preventDefault()方法,如果存在则调用该方法。如果preventDefault()方法不存在,则将returnValue设置为false。下面是使用这个方法的例子:
1 var link = document.getElementById("myLink"); 2 link.onclick = function(evnet) { 3 evnet = EventUtil.getEvent(event); 4 EventUtil.preventDefault(event); 5 };
以上代码可以确保在所有浏览器中单击该链接都不会打开另一个页面。
第四个方法是stopPropagation(),其实现方式类似。首先尝试使用DOM方法阻止事件流,否则就使用cancelBubble属性。下面是使用这个方法的例子:
1 var btn = document.getElementById("myBtn"); 2 btn.onclick = function(event) { 3 alert("Clicked"); 4 event = EventUtil.getEvent(event); 5 EventUtil.stopPropagation(event); 6 }; 7 8 document.body.onclick = function(event) { 9 alert("Body clicked"); 10 };
在此,首先使用EventUtil.getEvent()取得了event对象,然后又将其传入到EventUtil.stopPropagation()。注意:由于IE不支持事件捕获,因此这个方法在跨浏览器的情况下,也只能用来阻止事件冒泡。