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

2010-12-15 03:04

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

by 周尚武

at 2010-12-14 19:04:00

original http://www.cnblogs.com/275095923/archive/2010/12/14/1905970.html

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;
}
}

看完了全文,希望您会了,祝学习愉快!

 

 

作者: 周尚武 发表于 2010-12-14 19:04 原文链接

评论: 0 查看评论 发表评论


最新新闻:
· Mozilla要重新发明浏览器(2010-12-14 18:25)
· 做有市场思维的开发人员(2010-12-14 18:22)
· Hudson逃离Oracle(2010-12-14 18:18)
· Opera技术布道专家谢子斌谈HTML5(2010-12-14 18:16)
· 商业周刊:腾讯的成长令互联网权贵感到震惊(2010-12-14 18:14)

编辑推荐:WP7有约(二):课后作业

网站导航:博客园首页  我的园子  新闻  闪存  小组  博问  知识库