javascript实现Observer模式来管理多个事件回调


《实战ajax》第四章介绍了这样的一个模型,与java中的事件处理模型相一致,观察者——监听者模式,感觉很酷:)。比如,我要对ID为mousemat的div标签的onclick事件增加两个事件writestatus()和drawThumbnail(),更新状态栏和重定位鼠标位置这两个事件,典型的代码应该像这样:

window.onload=function(){
  var mat=document.getElementById('mousemat');
  mat.onclick=mouseObserver;
  cursor=document.getElementById('cursor');
}

function mouseObserver(event){
  var e=window.event||event;
  writeStatus(e)
  drawThumbnail(e)
}
这样的方式目前看起来还算清晰,但是当事件增多时将不可避免地复杂起来,如果我们能像java中的事件处理模型那样直接addListener该多好,书中给出了例子:

window.onload=function(){
  var mat=document.getElementById('mousemat');
  cursor=document.getElementById('cursor');

  var mouseRouter=new jsEvent.EventRouter(mat,"onclick");
  mouseRouter.addListener(writeStatus);
  mouseRouter.addListener(drawThumbnail);
}

引入了一个EventRouter对象,此对象完整代码如下:

requires extras-array.js

var jsEvent=new Array();

jsEvent.EventRouter=function(el,eventType){
  this.lsnrs=new Array();
  this.el=el;
  el.eventRouter=this;
  el[eventType]=jsEvent.EventRouter.callback;
}

jsEvent.EventRouter.prototype.addListener=function(lsnr){
  this.lsnrs.append(lsnr,true);
}

jsEvent.EventRouter.prototype.removeListener=function(lsnr){
  this.lsnrs.remove(lsnr);
}


jsEvent.EventRouter.prototype.notify=function(e){
  var lsnrs=this.lsnrs;
  for(var i=0;i<lsnrs.length;i++){
    var lsnr=lsnrs[i];
    lsnr.call(this,e);
  }
}

jsEvent.EventRouter.callback=function(event){
  var e=event || window.event;
  var router=this.eventRouter;
  router.notify(e)
}
 
这段代码并不难理解,实现了一个事件顺序数组,增加的监听器函数通过Function.call()调用。两个方法addListener和removeListener真正实现了清晰的事件模型。
posted @ 2007-01-20 19:43  子午  阅读(548)  评论(0编辑  收藏  举报