百度空间 | 百度首页 
 
查看文章
 
JavaScript面向对象编程[三] 自定义事件
2009-09-07 17:13

上一篇给foo类增加了
addEvent和removeEvent方便事件的注册与注销

这次总结下自定义事件的几种方法

程序代码

<script type=”text/javascript”>
<!–

var foo = function(){ this.init.apply(this,arguments);};

foo.prototype = {
init:function(_name){
this.name = _name;
this.addEvent(’click’,document,this.say,this,’hello world!’);
},
say:function(_ev,_word){
alert(this.name +’:’ +_word);
this.stop();
this.onSay(_word);
},
stop:function(){
this.removeEvent(’click’,document,this.say);
},
addEvent:function(_event,_element,_fn,_scope,_args){
var args = Array.prototype.slice.call(arguments, 0);
ev = args.shift(),
element = args.shift(),
fn = args.shift(),
scope = args.length>0?args.shift():window;
element['e'+ev+fn] =   function(_ev){
_ev == _ev || window.event;
args.unshift(_ev);
fn.apply(scope,args);
};
if (element.addEventListener) {
element.addEventListener(ev, element['e'+ev+fn], false);
} else if (element.attachEvent) {
element.attachEvent(”on” +ev, element['e'+ev+fn]);
}
},
removeEvent:function(_event,_element,_fn){
if (_element.removeEventListener) {
_element.removeEventListener(_event, _element['e'+_event+_fn], false);
} else if (_element.detachEvent) {
_element.detachEvent(”on” +_event, _element['e'+_event+_fn]);
}
try {
delete _element['e'+_event+_fn];
}catch(_ex){
_element['e'+_event+_fn] = null;
}
},
onSay:function(){}

}

var a = new foo(’llinzzi’);
a.onSay = function(_word){
alert(’事件:’+this.name +’刚说了’+ _word);
}

HTML代码
<br /> <html><br /> <head></p> <p><meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ ><br /> <meta name=”keywords” content=”" ><br /> <meta name=”description” content=”" ><br /> </head><br /> <body><br /> <mce:script type=mce-”text/javascript”><!– var foo = function(){ this.init.apply(this,arguments);}; foo.prototype = { init:function(_name){ this.name = _name; this.addEvent(’click’,document,this.say,this,’hello world!’); }, say:function(_ev,_word){ alert(this.name +’:’ +_word); this.stop(); this.onSay(_word); }, stop:function(){ this.removeEvent(’click’,document,this.say); }, addEvent:function(_event,_element,_fn,_scope,_args){ var args = Array.prototype.slice.call(arguments, 0); ev = args.shift(), element = args.shift(), fn = args.shift(), scope = args.length>0?args.shift():window; element['e'+ev+fn] = function(_ev){ _ev == _ev || window.event; args.unshift(_ev); fn.apply(scope,args); }; if (element.addEventListener) { element.addEventListener(ev, element['e'+ev+fn], false); } else if (element.attachEvent) { element.attachEvent(&#34;on&#34; +ev, element['e'+ev+fn]); } }, removeEvent:function(_event,_element,_fn){ if (_element.removeEventListener) { _element.removeEventListener(_event, _element['e'+_event+_fn], false); } else if (_element.detachEvent) { _element.detachEvent(&#34;on&#34; +_event, _element['e'+_event+_fn]); } try { del&#101;te _element['e'+_event+_fn]; }catch(_ex){ _element['e'+_event+_fn] = null; } }, onSay:function(){} } var a = new foo(’llinzzi’); a.onSay = function(_word){ alert(’事件:’+this.name +’刚说了’+ _word); } // –></mce:script><br /> </body><br /> </html><br />

增加了个onSay的事件,在类定义的时候只定义成空函数,然后在需要的时候调用,定义具体的方法是在类实例化后,给实例中的onSay

缺点是只能定义一次的onSay的回调,如果多次定义后面的会把前面的覆盖掉,修改一下。

程序代码

var foo = function(){ this.init.apply(this,arguments);};

foo.prototype = {
init:function(_name){
this.name = _name;
this.addEvent(’click’,document,this.say,this,’hello world!’);
},
say:function(_ev,_word){
alert(this.name +’:’ +_word);
this.stop();
this._onSay(_word);
},
stop:function(){
this.removeEvent(’click’,document,this.say);
},
addEvent:function(_event,_element,_fn,_scope,_args){
var args = Array.prototype.slice.call(arguments, 0);
ev = args.shift(),
element = args.shift(),
fn = args.shift(),
scope = args.length>0?args.shift():window;
element['e'+ev+fn] =   function(_ev){
_ev == _ev || window.event;
args.unshift(_ev);
fn.apply(scope,args);
};
if (element.addEventListener) {
element.addEventListener(ev, element['e'+ev+fn], false);
} else if (element.attachEvent) {
element.attachEvent(”on” +ev, element['e'+ev+fn]);
}
},
removeEvent:function(_event,_element,_fn){
if (_element.removeEventListener) {
_element.removeEventListener(_event, _element['e'+_event+_fn], false);
} else if (_element.detachEvent) {
_element.detachEvent(”on” +_event, _element['e'+_event+_fn]);
}
try {
delete _element['e'+_event+_fn];
}catch(_ex){
_element['e'+_event+_fn] = null;
}
},
_onSay:function(){
if(!this._onSayArray) return;
for(var i=0; i<this._onSayArray.length; i++){
this._onSayArray[i].apply(this,arguments);
}
},
addOnSay:function(_fn){
if(!this._onSayArray) this._onSayArray = new Array();
this._onSayArray.push(_fn);
}
}

var a = new foo(’llinzzi’);
a.addOnSay(function(_word){
alert(’事件1:’+this.name +’刚说了’+ _word);
});
a.addOnSay(function(_word){
alert(’事件2:’+this.name +’刚说了’+ _word);
});

HTML代码
<br /> <html><br /> <head></p> <p><meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ ><br /> <meta name=”keywords” content=”" ><br /> <meta name=”description” content=”" ><br /> </head><br /> <body><br /> <mce:script type=mce-”text/javascript”><!– var foo = function(){ this.init.apply(this,arguments);}; foo.prototype = { init:function(_name){ this.name = _name; this.addEvent(’click’,document,this.say,this,’hello world!’); }, say:function(_ev,_word){ alert(this.name +’:’ +_word); this.stop(); this._onSay(_word); }, stop:function(){ this.removeEvent(’click’,document,this.say); }, addEvent:function(_event,_element,_fn,_scope,_args){ var args = Array.prototype.slice.call(arguments, 0); ev = args.shift(), element = args.shift(), fn = args.shift(), scope = args.length>0?args.shift():window; element['e'+ev+fn] = function(_ev){ _ev == _ev || window.event; args.unshift(_ev); fn.apply(scope,args); }; if (element.addEventListener) { element.addEventListener(ev, element['e'+ev+fn], false); } else if (element.attachEvent) { element.attachEvent(&#34;on&#34; +ev, element['e'+ev+fn]); } }, removeEvent:function(_event,_element,_fn){ if (_element.removeEventListener) { _element.removeEventListener(_event, _element['e'+_event+_fn], false); } else if (_element.detachEvent) { _element.detachEvent(&#34;on&#34; +_event, _element['e'+_event+_fn]); } try { del&#101;te _element['e'+_event+_fn]; }catch(_ex){ _element['e'+_event+_fn] = null; } }, _onSay:function(){ if(!this._onSayArray) return; for(var i=0; i <this._onSayArray.length; i++){ this._onSayArray[i].apply(this,arguments); } }, addOnSay:function(_fn){ if(!this._onSayArray) this._onSayArray = new Array(); this._onSayArray.push(_fn); } } var a = new foo(’llinzzi’); a.addOnSay(function(_word){ alert(’事件1:’+this.name +’刚说了’+ _word); }); a.addOnSay(function(_word){ alert(’事件2:’+this.name +’刚说了’+ _word); }); // –></mce:script><br /> </body><br /> </html><br />

实例通过addOnSay方法来增加事件响应,可以增加多个。

缺点,代码繁琐,如果要增加addOnSayAfter addOnSayBefore 就要增加很多代码。

再修改一下

程序代码

var foo = function(){ this.init.apply(this,arguments);};

foo.prototype = {
init:function(_name){
this.name = _name;
this.addEvent(’click’,document,this.say,this,’hello world!’);
},
say:function(_ev,_word){
this.fireEvent(’saybefore’,_word);
alert(this.name +’:’ +_word);
this.stop();
this.fireEvent(’sayafter’,_word);
},
stop:function(){
this.removeEvent(’click’,document,this.say);
},
addEvent:function(_event,_element,_fn,_scope,_args){
var args = Array.prototype.slice.call(arguments, 0);
ev = args.shift(),
element = args.shift(),
fn = args.shift(),
scope = args.length>0?args.shift():window;
element['e'+ev+fn] =   function(_ev){
_ev == _ev || window.event;
args.unshift(_ev);
fn.apply(scope,args);
};
if (element.addEventListener) {
element.addEventListener(ev, element['e'+ev+fn], false);
} else if (element.attachEvent) {
element.attachEvent(”on” +ev, element['e'+ev+fn]);
}
},
removeEvent:function(_event,_element,_fn){
if (_element.removeEventListener) {
_element.removeEventListener(_event, _element['e'+_event+_fn], false);
} else if (_element.detachEvent) {
_element.detachEvent(”on” +_event, _element['e'+_event+_fn]);
}
try {
delete _element['e'+_event+_fn];
}catch(_ex){
_element['e'+_event+_fn] = null;
}
},
fireEvent:function(){
var args = Array.prototype.slice.call(arguments, 0);
var _event = args.shift();
if(!this.cusEvents) return;
if(!this.cusEvents[_event]) return;
for(var i=0; i<this.cusEvents[_event].length; i++){
this.cusEvents[_event][i].apply(this,args);
}
},
catchEvent:function(_event,_fn){
if(!this.cusEvents) this.cusEvents = {}
if(!this.cusEvents[_event]) this.cusEvents[_event] = new Array();
this.cusEvents[_event].push(_fn);
}
}

var a = new foo(’llinzzi’);

a.catchEvent(’saybefore’,function(_word){
alert(’事件1:’+this.name +’想说’+ _word);
});

a.catchEvent(’sayafter’,function(_word){
alert(’事件2:’+this.name +’刚说了’+ _word);
});

HTML代码
<br /> <html><br /> <head></p> <p><meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ ><br /> <meta name=”keywords” content=”" ><br /> <meta name=”description” content=”" ><br /> </head><br /> <body><br /> <mce:script type=mce-”text/javascript”><!– var foo = function(){ this.init.apply(this,arguments);}; foo.prototype = { init:function(_name){ this.name = _name; this.addEvent(’click’,document,this.say,this,’hello world!’); }, say:function(_ev,_word){ this.fireEvent(’saybefore’,_word); alert(this.name +’:’ +_word); this.stop(); this.fireEvent(’sayafter’,_word); }, stop:function(){ this.removeEvent(’click’,document,this.say); }, addEvent:function(_event,_element,_fn,_scope,_args){ var args = Array.prototype.slice.call(arguments, 0); ev = args.shift(), element = args.shift(), fn = args.shift(), scope = args.length>0?args.shift():window; element['e'+ev+fn] = function(_ev){ _ev == _ev || window.event; args.unshift(_ev); fn.apply(scope,args); }; if (element.addEventListener) { element.addEventListener(ev, element['e'+ev+fn], false); } else if (element.attachEvent) { element.attachEvent(&#34;on&#34; +ev, element['e'+ev+fn]); } }, removeEvent:function(_event,_element,_fn){ if (_element.removeEventListener) { _element.removeEventListener(_event, _element['e'+_event+_fn], false); } else if (_element.detachEvent) { _element.detachEvent(&#34;on&#34; +_event, _element['e'+_event+_fn]); } try { del&#101;te _element['e'+_event+_fn]; }catch(_ex){ _element['e'+_event+_fn] = null; } }, fireEvent:function(){ var args = Array.prototype.slice.call(arguments, 0); var _event = args.shift(); if(!this.cusEvents) return; if(!this.cusEvents[_event]) return; for(var i=0; i <this.cusEvents[_event].length; i++){ this.cusEvents[_event][i].apply(this,args); } }, catchEvent:function(_event,_fn){ if(!this.cusEvents) this.cusEvents = {} if(!this.cusEvents[_event]) this.cusEvents[_event] = new Array(); this.cusEvents[_event].push(_fn); } } var a = new foo(’llinzzi’); a.catchEvent(’saybefore’,function(_word){ alert(’事件1:’+this.name +’想说’+ _word); }); a.catchEvent(’sayafter’,function(_word){ alert(’事件2:’+this.name +’刚说了’+ _word); }); // –></mce:script><br /> </body><br /> </html><br />

最后如果将catchEvent fireEvent addEvent removeEvent 单独放在一个类.EventHeloper
将addEvent和catchEvent整合
EventHeloper.addEvent(element/object,dom event/custom event,callback) 这样还是很方便的。

程序代码

EventHelper = {
Events:{Dom:{},Custom:{}},
addEvent:function(_object,_event,_fn,_scope,_args){
var args = Array.prototype.slice.call(arguments, 0),
obj = args.shift(),
ev = args.shift(),
fn = args.shift(),
scope = args.length>0?args.shift():window;
var eType = obj.nodeType?’Dom’:'Custom’;
var fun;
if(eType==’Dom’){
sfn = function(_ev){
_ev == _ev || window.event;
args.unshift(_ev);
fn.apply(scope,args);
}
if (obj.addEventListener) {
obj.addEventListener(ev,sfn, false);
} else if (obj.attachEvent) {
obj.attachEvent(”on” +ev,sfn);
}
}else {
sfn = function(){
var __sargs = Array.prototype.slice.call(arguments, 0);
var _sargs = __sargs.concat(args);
fn.apply(scope,_sargs);
}
}
fun = { fn:fn,sfn:sfn };
this.Events[eType][obj] = this.Events[eType][obj] || {};
this.Events[eType][obj][ev] = this.Events[eType][obj][ev] || new Array();
this.Events[eType][obj][ev].push(fun);
},
removeEvent:function(_object,_event,_fn){
var obj = _object,
ev = _event,
fn = _fn;
var eType = obj.nodeType?’Dom’:'Custom’;
if(!this.Events[eType][obj]) return;

var fun;
for( var i=0; i<this.Events[eType][obj][ev].length;i++){
if(fn == this.Events[eType][obj][ev][i].fn){
fun = this.Events[eType][obj][ev][i].sfn;
this.Events[eType][obj][ev].splice(i,1);
break;
}
}
if(eType==’Dom’){
if (obj.removeEventListener) {
obj.removeEventListener(ev, fun, false);
} else if (obj.detachEvent) {
obj.detachEvent(”on” + ev, fun);
}
}

},
fireEvent:function(_object,_event){
var args = Array.prototype.slice.call(arguments, 0),
obj = args.shift(),
ev = args.shift();
var eType = ‘Custom’;
if((!this.Events[eType][obj]) || (!this.Events[eType][obj][ev])) return;

for(var i=0; i<this.Events[eType][obj][ev].length; i++){
this.Events[eType][obj][ev][i].sfn.apply(window,args);
}
}
}

修改一下演示的例子

HTML代码
<br /> <html><br /> <head></p> <p><meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ ><br /> <meta name=”keywords” content=”" ><br /> <meta name=”description” content=”" ><br /> </head><br /> <body><br /> <mce:script type=mce-”text/javascript”><!– EventHelper = { Events:{Dom:{},Custom:{}}, addEvent:function(_object,_event,_fn,_scope,_args){ var args = Array.prototype.slice.call(arguments, 0), obj = args.shift(), ev = args.shift(), fn = args.shift(), scope = args.length>0?args.shift():window; var eType = obj.nodeType?’Dom’:'Custom’; var fun; if(eType==’Dom’){ sfn = function(_ev){ _ev == _ev || window.event; args.unshift(_ev); fn.apply(scope,args); } if (obj.addEventListener) { obj.addEventListener(ev,sfn, false); } else if (obj.attachEvent) { obj.attachEvent(&#34;on&#34; +ev,sfn); } }else { sfn = function(){ var __sargs = Array.prototype.slice.call(arguments, 0); var _sargs = __sargs.concat(args); fn.apply(scope,_sargs); } } fun = { fn:fn,sfn:sfn }; this.Events[eType][obj] = this.Events[eType][obj] || {}; this.Events[eType][obj][ev] = this.Events[eType][obj][ev] || new Array(); this.Events[eType][obj][ev].push(fun); }, removeEvent:function(_object,_event,_fn){ var obj = _object, ev = _event, fn = _fn; var eType = obj.nodeType?’Dom’:'Custom’; if(!this.Events[eType][obj]) return; var fun; for( var i=0; i <this.Events[eType][obj][ev].length;i++){ if(fn == this.Events[eType][obj][ev][i].fn){ fun = this.Events[eType][obj][ev][i].sfn; this.Events[eType][obj][ev].splice(i,1); break; } } if(eType==’Dom’){ if (obj.removeEventListener) { obj.removeEventListener(ev, fun, false); } else if (obj.detachEvent) { obj.detachEvent(&#34;on&#34; + ev, fun); } } }, fireEvent:function(_object,_event){ var args = Array.prototype.slice.call(arguments, 0), obj = args.shift(), ev = args.shift(); var eType = ‘Custom’; if((!this.Events[eType][obj]) || (!this.Events[eType][obj][ev])) return; for(var i=0; i<this.Events[eType][obj][ev].length; i++){ this.Events[eType][obj][ev][i].sfn.apply(window,args); } } } var foo = function(){ this.init.apply(this,arguments);}; foo.prototype = { init:function(_name){ this.name = _name; EventHelper.addEvent(document,’click’,this.say,this,’hello world!’); }, say:function(_ev,_word){ EventHelper.fireEvent(this,’saybefore’,_word); alert(this.name +’:’ +_word); this.stop(); EventHelper.fireEvent(this,’sayafter’,_word); }, stop:function(){ EventHelper.removeEvent(document,’click’,this.say); } } var a = new foo(’llinzzi’); function sayBefore(_word,_word2){ alert(’事件1:’+this.name +’想说’+ _word+_word2); } function sayAfter(_word){ alert(’事件2:’+this.name +’刚说了’+ _word); } EventHelper.addEvent(a,’saybefore’,sayBefore,a,’外部的数据’); //EventHelper.removeEvent(a,’saybefore’,sayBefore); EventHelper.addEvent(a,’sayafter’,sayBefore,a); // –></mce:script><br /> </body><br /> </html><br />

上面例子的 EventHelper.addEvent方法可以增加自定义事件或者原生的事件
EventHelper.addEvent(document,’click’,function(){alert(’hello’);}); // 原生事件
EventHelper.addEvent(foo,’say’,function(){alert(’hello’);}); // 自定义时间

对应的EventHelper.removeEvent也可以移除自定义事件。


类别:Javascript | 添加到搜藏 | 浏览() | 评论 (0)
 
最近读者:
 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码: 请点击后输入四位验证码,字母不区分大小写
      

     

©2009 Baidu