跨浏览器事件处理

7 分钟读完

DOM事件类型在不同的浏览器之间并未能够完全统一,所以当我们想要兼容低版本的各种浏览器的时候,就需要考虑跨浏览器的事件处理。
本文将尽可能全面的讲述跨浏览器事件处理的解决方案。 ***

背景知识:

在讨论解决方案之前,我们先来看看关于事件的处理在不同的浏览器中都有哪些方面的不同。

1.DOM Level 0 的事件绑定,解绑和 Event对象

在0级事件处理中,绑定事件是通过document对象的on+事件类型(如onclick)属性来绑定事件的(将这个属性设置为null可以解绑事件)。并为该属性提供一个事件处理函数的引用。下面是一个简单的例子:

let myElement = document.getElementById("someId");
myElement.onclick = ClickHandle;

function ClickHandle(event){  //在IE6-IE8浏览器中,不会传入event对象,而event对象作为window对象的一个属性
	/*do something when element been clicked.*/
}

注意,在上面的例子中,事件处理函数ClickHandle在IE6-IE8浏览器中,不会传入一个Event对象作为参数(而是使用window.event来访问),所以event形参并不会接收到一个参数。而在其他浏览器中,该函数会接受到一个Event对象,以供在函数中使用。

2.DOM Level 2 的事件绑定和解除绑定方法:
  • 在IE6 - IE10中,我们可以使用attachEvent('on'+事件类型,事件处理函数)来绑定事件;用detachEvent('on'+事件类型,事件处理函数)来解除事件的绑定 (在IE11+中使用会报错)
  • 在其他浏览器和IE9+中,我们使用addEventListener(事件类型,事件处理函数,是否为捕获类型)来绑定事件;用removeEventListener(事件类型,事件处理函数,是否为捕获类型)来解除事件绑定。
3.IE浏览器和其他浏览器event对象的属性和方法不完全相同:
  • event事件的目标元素:在attachEvent()绑定的事件处理程序中对应的是event对象的srcElement属性;addEventListener()对应的是target属性。
  • 取消事件冒泡:在attachEvent()绑定的事件处理程序中对应的是event对象的cancelBubble属性;addEventListener()对应的是stopPropagation()方法。
  • 取消默认事件(如链接的click事件发生后会跳转到href,表单的submit类型的button会提交表单):在attachEvent()绑定的事件处理程序中对应的是event对象的returnValue属性,addEventListener()对应的是preventDefault()方法。

跨浏览器的事件处理解决方案:

了解了以上的一些跨浏览器问题,我们来看一下具体的解决方案是怎样的:

let myElement = document.getElementById("someId");

// 绑定事件
if(myElement.addEventListener) {
	myElement.addEventListener("click",Handler,false);
} 
else if(myElement.attachEvent) {  //IE8及IE8之前的版本
	myElement.attachEvent("onclick",Handler);
}
else {  //IE6之前的版本
	myElement.onclick = HandleLevelZero;
}
//解绑事件
if(myElement.removeEventListener) {
	myElement.addEventListener("click",Handler,false);
} 
else if(myElement.detachEvent) {  //IE8及IE8之前的版本
	myElement.attachEvent("onclick",Handler);
}
else { //IE6之前的版本
	myElement.onclick = null;
}



/* 事件处理函数 */

// DOM Level 0 事件处理函数
function HandleLevelZero(event) {  
	let evt = event?event:window.event;  // 获取Event对象

}

// DOM Level 2 事件处理函数
function Handler(event) {  
	let theTarget = event.target?event.target:event.srcElement; // 获取目标元素
	
	// 取消冒泡
	if(event.stopPropagation) {  // 注意这里不能检测cancelBubble,因为其值可能为false
		event.stopPropogation();
	}
	else{
		event.cancelBubble = true; 
	}

	//取消默认事件
	if(event.preventDefault) {
		event.preventDefault();
	}
	else {
		event.returnValue = false;
	}
} 

以上就是一些常见的事件处理操作。在实际的使用过程中,我们可以根据我们的需要,将这些操作封装起来,在这里就不做实际演示了。

更新时间: