您的位置:首页 > Web前端 > JavaScript

【web开发】关于Javascript事件注册的那些事

2010-12-14 19:04 162 查看
Javascript由于使用浏览器平台众多,所以它自然而然有很多语言特性都会有些故事,今天与大家一起分享一下关于事件的那些事,事件注册大致可以分为以下三类方法。

一、传统事件注册方式其实是个很好方式,而且大部分时候都表现的很好。

优点很多:

1、 不用分支,有最好的兼容性。

2、 this指向触发事件的元素,这点很重要。

缺点也是有地:

一个元素只能绑定一个事件处理函数。

只支持冒泡,不支持捕获阶段,不过这捕获我还真不知道怎么用。

二、W3C 的addEventListener方法看起来也很不错。对应移除方法为removeEventListener

优点也有很多

1、 this指向触发事件的元素,这点很重要。

2、 可以绑定任意多个处理函数。

3、 可以支持冒泡与捕获,不过我只用它的冒泡。

缺点很显然是ie不行,得用下面提到的attachEvent。

三、IE的attachEvent。对应方法为detachEvent

优点:

1、 我这里就提一个,可以绑定多个处理函数。因为实在没有太多的优点。

缺点:

1、 最大的缺点,事件处理函数内this指向的window,真不知道为什么要这样搞。谁告诉我一下。

2、 绑定时要用onxx形式如:window.attachEvent(”onload”,handler);

总结来说,比较大的差异在于:

IE的事件处理函数要得到event对象,得从window.event那里取,w3c可以从事件处理函数的第一个参数得到。IE注册事件要用onxx的形式,w3c不用。

通过上面一些差异性的了解,我想下面要写一对addEvent,removeEvent方法就没有什么问题了,通过走不同的分支即可以实现。并且通过闭包特性也能很好的解决this指向的问题。

function addEvent(obj, type, fn){
if (obj.attachEvent) {
obj[type + fn] = function(){
fn.call(obj, window.event);//同时解决this关键字与event对象的问题
};
obj.attachEvent('on' + type, obj[type + fn]);
}
else {
obj.addEventListener(type, fn, false);
}
}

function removeEvent(obj, type, fn){
if (obj.detachEvent) {
obj.detachEvent('on' + type, obj[type + fn]);
obj[type + fn] = null;
}
else {
obj.removeEventListener(type, fn, false);
}
}


当然上面这种obj[type + fn ]确实不是很好,您有时间去改进下,但是这里我不推荐使用这种方法,而是推荐使用传统方式来做事件管理,优点那是相当的多,使用传统方式有更好更广的兼容性,不用去记不同的接口,this问题不用单独处理。

var Event = {
guid:1,
addEvent:function(elem,type,fn){
fn.guid = Event.guid++;
elem.events = elem.events || {};
var handler = elem.events[type];
if(!handler){
handler = elem.events[type] = {};
if(elem["on"+type]){
handler[0] = elem["on"+type];
}
}
handler[fn.guid] = fn;
elem["on"+type] = Event.fireEvent;
},
fireEvent:function(e){
e = e || Event.fixEvent(window.event);
var handlers = this.events[e.type];
var returnValue = true;
for (var i in handlers) {
if (handlers[i].call(this, e) === false) {
returnValue = false;
}
}
return returnValue;
},
removeEvent:function(elem,type,fn){
if (elem.events && elem.events[type]) {
delete elem.events[type][fn.guid];
}
},
clearEvent:function(elem,type){
if (elem.events && elem.events[type]) {
elem.events[type] = {};
}
},
fixEvent:function(e){
//光标相对于页面
e.pageX = e.clientX + document.body.scrollLeft;
e.pageY = e.clientY + document.body.scrollLeft;
//光标相对于触发事件的对象
e.layerX = e.offsetX;
e.layerY = e.offsetY;
e.preventDefault = function(){
e.returnValue = false;
return false;
}
e.stopPropagation = function(){
e.cancelBubble = true;
}
return e;
}
}


看完了全文,希望您会了,祝学习愉快!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: