讀古今文學網 > 編寫高質量代碼:改善JavaScript程序的188個建議 > 建議129:自定義事件 >

建議129:自定義事件

事件是一種稱做觀察者的設計模式,是一種創建鬆散耦合代碼的技術。對象可以發佈事件,以表示該對像聲明週期中某個有趣的時刻到了。其他對象可以觀察該對象,等待有趣的時刻到來並通過運行代碼來響應。觀察者模式由兩類對像組成:主體和觀察者。

❑主體負責發佈事件,同時觀察者通過訂閱這些事件來觀察主體。

❑主體並不知道觀察者的任何事情,它可以獨自存在並正常運作(即使觀察者不在)。

自定義事件就是對已經存在的事件進行包裝,也就是說,自定義事件在執行的時候還是需要依賴已有的鍵盤、鼠標、HTML等事件來執行,或者由其他函數觸發執行,這裡的觸發是指直接調用自定義事件中聲明的某個接口方法,以便不斷執行添加到自定義事件中的函數。

自定義事件內部有一個事件存儲器,它根據添加的事件的類型不同來存儲各個類的事件執行函數,當再次觸發這類事件時,就輪詢執行添加到該類型下的函數。自定義事件隱含的作用是創建一個管理事件的對象,讓其他對像監聽那些事件。基於自定義事件的原理,可以想像自定義事件很多時候用於實現訂閱—發佈—接收性質的功能。

❑基本模式:


function EventTarget{

this.handlers={};

}

EventTarget.prototype={

constructor:EventTarget,

addHandler:function(type,handler){

if(typeof this.handlers[type]=="undefined"){

this.handlers[type]=;

}

this.handlers[type].push(handler);

},

fire:function(event){

if(!event.target){

event.target=this;

}

if(this.handlers[event.type]instanceof Array){

var handlers=this.handlers[event.type];

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

handlers[i](event);

}

}

},

removeHandler:function(type,handler){

if(this.handlers[type]instanceof Array){

var handlers=this.handlers[type];

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

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

break;

}

}

Handlers.splice(i,1);

}

}

};


❑使用EventTarget類型的自定義事件的方法如下:


function handleMessage(event){

alert("message received:"+event.message);

}

//創建一個新對像

var target=new EventTarget;

//添加一個事件處理程序

target.addHandler("message",handleMessage);

//觸發事件

target.fire({

type:"message",

message:"hello world!"

});

//刪除事件處理程序

target.removeHandler("message",handleMessage);


❑使用實例:


function Person(name,age){

eventTarget.call(this);

this.name=name;

this.age=age;

}

inheritPrototype(Person,EventTarget);

Person.prototype.say=function(message){

this.fire({

type:"message",

message:message

});

};

function handleMessage(event){

alert(event.target.name+"says:"+event.message);

}

//創建新person

var person=new Person("Nicholas",29);

//添加一個事件處理程序

Person.addHandler("message",handleMessage);

//在該對像上調用一個方法,它觸發消息事件

person.say("Hi there");