(function(){ function EvtCenter(){ this.index=1; this.ids=[]; this.items={}; this.channels={}; } EvtCenter.prototype.getID=function(obj){ var id,i; for(i=0;i<this.ids.length;i++){ if(this.items[this.ids[i]]===obj){ return this.ids[i]; } } id = this.index++; this.ids.push(id); this.items[id]=obj; return id; } EvtCenter.prototype.getObj=function(id){return this.items[id];} function Eventable(fn){ fn.prototype.on=function(center,name,callback){ if(!(center instanceof EvtCenter))return; var channel=center.channels[name]; var id=center.getID(this); if(!channel) center.channels[name]={}; center.channels[name][id]=callback; } fn.prototype.off=function(center,name){ if(!(center instanceof EvtCenter))return; var channel=center.channels[name]; var id=center.getID(this); if(channel&&channel[id]){delete center.channels[name][id]} } fn.prototype.trigger=function(center,name,args){ if(!(center instanceof EvtCenter))return; var self=this; var channel=center.channels[name]; if(channel){ for(var id in channel){ (function(obj,callback){ setTimeout(function(){ callback&&callback.call(obj,{sender:self,data:args}) },0) })(center.getObj(id),channel[id]); } } } } window.EvtCenter=EvtCenter; window.Eventable=Eventable; })();//event
原生事件只能绑定在DOM元素上,要想在任意Object上绑定事件,还得自己弄
我采用了订阅发布模式
对象的识别上有点纠结,没有像jquery那样污染对象(添加uid),目前是用的对象缓存,然后遍历,性能上肯定没有直接添加uid好。。。
还要配合消息中心使用,有点小麻烦啊
(function(){ var CENTER = new EvtCenter(); function Obj(){ this.on(CENTER,"load",this.onload) } Obj.prototype.onload=function(e){ console.log('loaded'); } Eventable(Obj); var obj=new Obj(); function Loader(){ var self=this; setTimeout(function(){ self.trigger(CENTER,"load"); },500) } Eventable(Loader); new Loader(); })()