Javascript之自定义事件

1 篇文章 0 订阅
1 篇文章 0 订阅
鉴于之前看的一些 javascript 资料和自己之前写的 AS 代码, javascript 的事件定义的还是比较充分的,足够满足日常的需求。

但目前发现唯一不足的就是,js的自定义事件,目前还不被大部分浏览器支持,这给开发带来了一些不便。虽然js内部定义的事件丰富,但是也仅限于UI事件,BOM事件和DOM事件,对于某些领域(比如自己开发的控件,游戏等需要自己在某些时候调用特定方法,或者是习惯于观察者模式的开发者)来说,这也是一种缺陷吧。

为此,鄙人写了个js类来模拟javascript中的事件,代码如下:

BaseEvent.js

function BaseEvent(type,data){

var This = this;

This.type = type;//String

This.data = data;//Object

function Constructor(){

}

Constructor();

}

这里定义一个类型和一个数据,数据用来传递参数。这里没有用到js原生的事件原理(捕获,目标,冒泡),是因为我们自己定义的事件,都是我们自己触发的,不需要这样的机制。这个类算是一个基类,可以拓展成各种子类,以及模块类(到时候写完会分享出来)。

EventDispatcher.js

function EventDispatcher(){

var This = this;

/**

  * type String

  * data [handlers]

  */

This.registeredData = {};

EventDispatcher.prototype.addCustomEventHandler = function(type,handler){

if((typeof type != "string")){

throw new Error("error event!!!");

}

if(!(typeof handler == "function")){

throw new Error("error method!!!");

}

if (This.registeredData[type] == null) {

This.registeredData[type] = new Array();

}

try {

if (This.registeredData[type].indexOf(handler) == -1) {

This.registeredData[type].push(handler);

}

} catch (e) {//IE8及以下的版本不支持indexOf方法

var len = This.registeredData[type].length;

if(len == 0){

This.registeredData[type].push(handler);

}

for (var i=0; i<len; i++) {

if(This.registeredData[type][i] === handler){

This.registeredData[type].push(handler);

break;

}

};

}

};

EventDispatcher.prototype.removeCustomEventHandler = function(type,handler){

if((typeof type != "string")){

throw new Error("error event!!!");

}

if(!(typeof handler == "function")){

throw new Error("error method!!!");

}

var handlers = This.registeredData[type];

var index;

try {

if((index = handlers.indexOf(handler)) != -1){

handlers.splice(index,1);

}

} catch (e) {//IE8及以下的版本不支持indexOf方法

for (var i=0,len = handlers.length; i<len; i++) {

if(handlers[i] === handler){

handlers.splice(i,1);

}

};

}

if(This.registeredData[type].length == 0)This.registeredData[type] = null;

};

EventDispatcher.prototype.dispatchCustomEvent = function(evt){

if(!(evt instanceof BaseEvent)){

throw new Error("error event!!!");

}

if(This.registeredData[evt.type] != null){

for (var i=0,len = This.registeredData[evt.type].length; i<len; i++) {

This.registeredData[evt.type][i](evt);

};

}

};

EventDispatcher.prototype.dispose = function(){

for(var arr in registeredData) {

while(arr.length != 0){

arr.shift();

}

};

registeredData = null;

};

}

这个类是事件注册/取消注册/监听的核心类,主要由3个方法组成:

一、addCustomEventHandler(type,handler)方法:

注册监听事件

type:String 事件类型

handler:function 处理方法

这和js原生的增加事件监听差不多,只不过,handler在回调的时候,传的是我们自己定义的事件对象,这有一个好处,js原生的事件对象的继承各种浏览器支持不一,用自己的对象可以自由增加删除属性和方法。

二、removeCustomEventHandler(type,handler)方法:

取消注册事件监听

这个方法和addCustomEventHandler类似,就是取消对某个事件的监听,也是和js原生的相似。需要注意的是,这里的handleraddCustomEventHandlerhandler必须是同一个对象的引用,才能移除监听。

三、dispatchCustomEvent(evt)方法

这个方法就是触发一个事件(自己定义的BaseEvent或子类)

这个方法就是我写这个东东的原因了,在js中,可以触发内部事件,但是,这样就给开发带来了一些不便,在游戏中,很多模块加载完,都是需要事件的,人物移动完成,技能释放完成,等等,都是需要事件的(这里讲得偏游戏了,不过不仅仅游戏,很多也是同样的道理)。用这个方法,就能很好的派发出自己的事件,让“观察者”来处理各自的需求了。这个方法也是模仿自AS3.0的事件机制。

四、dispose()方法

释放资源(游戏中这极其重要,别的领域应该也是吧)

用法:

首先,需要一个事件分发器dispatcher

var distpatcher = new EventDispatcher();

var fun = function(e){

alert(e.data);

//distpatcher.removeCustomEventHandler("cck",arguments.callee);//移除监听

};

distpatcher.addCustomEventHandler("cck",fun);

这里,就是注册监听,由于js实现接口比较麻烦,所以,dispatcher通常用作组合,作为对象的成员,这样,每个类都有自己的分发器,处理各自的事件请求。

然后,在需求触发事件的时候,调用如下代码:

distpatcher.dispatchCustomEvent(new BaseEvent("cck","i love you"));

这里,dispatcher派发了一个事件BaseEvent对象,type为"cck",data为"i love you"的String对象,在以上的监听中,就会弹出“i love you”警告框。

主要工作原理就差不多如上。

这可能有待改进,我也会再看看项目的代码和看看js的理论,多写一些方便大家使用的东西来共享,谢谢。

--------------------------------------------

源码地址http://download.csdn.net/detail/kukucckku/4527884

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值