传统javascript事件模型实现观察者模式2008-05-09在W3C新的事件模型框架中,IE和Mozilla都实现了相应的版本,IE的是attachEvent和detachEvent来实现元素事件的添加和删除,而Mozilla则是标准的addEventListener和 removeEventListener。在传统的javascript事件模型中,我们没办法为一个页面元素注册多个事件,只有靠自己来实现观察者模式。代码来自《ajax in action》,我添加了注释//命名空间 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); } }; //回调函数调用notify jsEvent.EventRouter.callback=function(event){ var e = event || window.event; var router = this.eventRouter; router.notify(e); }; Array.prototype.append = function(obj,nodup){ if(nodup){ this[this.length]=obj; } }; Array.prototype.remove = function(o) { var i = this.indexOf(o); if (i>-1) { this.splice(i,1); } return (i>-1); } };这里比较巧妙的就是el.eventRouter = this;//注册回调函数el[eventType] = jsEvent.EventRouter.callback;首先给el元素添加属性eventRouter是当前的EventRouter对象,然后,比如eventType假设为onclick,el是一个button元素,那么这里就是el[onclick]=jsEvent.EventRouter.callback;相当于el.onclick=jsEvent.EventRouter.callback;而请注意这个回调函数callback将首先得到元素的eventRouter对象,再调用此对象的notify方法触发所有注册的事件。再请注意notify函数里面这一行:lsnr.call(this,e);我们把event对象传入此函数作参,而var e = event || window.event;那么所有事件函数的第一个参数都将是event对象,避免了IE需要通过window.event得到的事件对象的浏览器不一致行为。使用此对象方式: var mat=document.getElementById("mousemat"); cursor=document.getElementById("cursor"); var mouseRouter=new jsEvent.EventRouter(mat,"onmousemove"); mouseRouter.addListener(writeStatus); mouseRouter.addListener(drawThumbnail);来源:http://www.blogjava.net/killme2008/archive/2007/03/16/104150.html
收藏该网址