搭建自己的base.js(1)-事件绑定

前言

从今天开始搭建自己的base.js,主要实现封装各浏览器兼容函数及常用操作。

JS中,最常见的浏览器兼容问题估计就是事件兼容问题了,比如获取事件对象、绑定事件等,我们可以将这些兼容函数放在一个全局对象EventUtil里面,减少全局变量污染,并保证随时扩充。

事件绑定

在Firefox、Chrome等支持DOM2的浏览器中,绑定事件使用的方法是addEventListener(type,handler,useCapture),三个参数分别表示事件类型、绑定事件的函数、是否在捕获阶段处理事件。

var btn1 = document.getElementById('btn1');

btn1.addEventListener('click',function(){
	alert('ok');
},false);

而在IE中,绑定事件使用的是attachEvent(type,handler),两个参数分别为事件类型、绑定事件的函数。由于IE8及以下版本只支持事件冒泡,所以绑定的事件都在事件冒泡阶段。在IE绑定事件的函数中,作用域是全局的,也就是说在绑定的事件函数中,this表示window,可使用call函数改变this指向。还有一点要注意的是,用attachEvent绑定多个相同类型的事件,后绑定的会先触发,这一点与DOM标准的刚好相反。

var btn1 = document.getElementById('btn1');

btn1.attachEvent('onclick',function(){ //事件类型要加on
	alert('ok');
     alert(this); //window });

  综上,兼容的事件绑定及事件移除函数如下:

var EventUtil = {
	//绑定事件
	addHandler: function(element,type,handler) {
		if(element.addEventListener) {
			element.addEventListener(type,handler,false);  //DOM2级,为保证浏览器兼容,在冒泡阶段处理事件
		} else if(element.attachEvent) {
			element.attachEvent('on'+type,function(){  //IE
				handler.call(element);  //修复IE中的this指向
			});  
		} else {
			element['on' + type] = handler;  //DOM0级
		}
	},
	// 解除事件绑定
	removeHandler:function(element,type,handler) {
		if(element.removeEventListener) {
			element.removeEventListener(type,handler,false);  //DOM2
		} else if(element.detachEvent) {
			element.detachEvent('on'+type, handler);  //IE
		} else {
			element['on'+type] = null;  //DOM0
		}
	}
}

  注意:绑定匿名函数的事件无法移除,因为绑定事件的解除绑定的参数必须完全一样才能解除,可以将代码用函数封装,传递函数的引用给事件函数。如以下代码先绑定后移除,点击没有反应:

function test() {
	alert('test');
}
EventUtil.addHandler(document,'click',test);
EventUtil.removeHandler(document,'click',test);

  

 获取事件对象

IE下用DOM0级on绑定事件,事件对象是window的属性,即window.event,而用attchEvent绑定的事件会在事件函数中传入一个事件对象并且window.event也可访问。

//IE
btn1.onclick = function(ev) {
	alert(ev);  //undefined
}

btn1.attachEvent('onclick',function(ev){
	alert(ev.target === window.event.target);  //true
});

  而在Firefox和Chrome下会在事件函数中传入事件对象,兼容的做法如下:

//获取事件对象
getEvent: function(event) {
	//IE下DOM0级事件不会传入event对象,而是用window.event,attachEvent会传入并且也有window.event
	//DOM2会传入event
	return event?event:window.event;
}

  获取目标对象

// 获取目标对象,引发事件的对象
getTarget:function(event) {
	//srcElement是IE专有
	return event.target || event.srcElement;
}

  阻止默认行为

// 阻止默认行为
	preventDefault: function(event) {
		if(event.preventDefault) {
			event.preventDefault();  //DOM
		} else {
			event.returnValue = false;  //IE
		}
	},

  阻止冒泡

// 阻止冒泡
	stopPropagation:function(event) {
		if(event.stopPropagation) {
			event.stopPropagation();  //DOM,Firefox,Chrome
		} else {
			cancelBubble = true;  //IE
		}
	},

  

 获取事件相关对象

如对某个元素监听mouseover事件时,鼠标是从另外一个元素移到该元素,这里可以获取另外一个元素。在Firefox和Chrome中,相关对象保存在event的relatedTarget属性中,IE则分成两个,一个是event.toElement,另一个是event.fromElement,两个选其一。

// 获取相关元素
	getRelatedTarget:function(event) {
		if(event.relatedTarget) {
			return event.relatedTarget;  //DOM
		} else if(event.toElement) {
			return event.toElement;  //IE的到某个元素
		} else if(event.fromElement) {
			return event.fromElement;  //IE的从哪个元素来
		} else {
			return null;
		}
	},

  

  

posted @ 2014-08-17 18:24  屋大明  阅读(788)  评论(0编辑  收藏  举报