Posted on 2007-03-16 09:19
dennis 閱讀(1894)
評論(0) 編輯 收藏 所屬分類:
web開發
??? 在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);?