最近在研究webRTC的封裝庫,在閱讀其源碼的過程中,對js原生的自定義事件封裝與調用機制有了新的認識,記錄下來分享給有需要的人。
正文開始:
JS的事件是基于“監聽和回調”機制的,回調函數負責對事件的處理。這種監聽與回調機制同樣可以應用在模塊、對象封裝中。通過自定義觸發事件,并且聲明回調函數,在恰當的時候對自定義事件進行觸發。這種事件模式可以代替函數調用機制,增強代碼的語義化;同時也可以將事件觸發看成一個模塊的對外接口,適合邏輯復雜的代碼的解耦,尤其利于js的邏輯操作部分與DOM操作部分的解耦。
Talking is cheap,let's show you the code!
首先我們定義一個事件模型,該模型脫胎于Nodejs的EventEmit:
functionEventEmitter() {
this.events= {};
}
//綁定事件函數
EventEmitter.prototype.on=function(eventName, callback) {
this.events[eventName] =this.events[eventName] || [];
this.events[eventName].push(callback);
};
//觸發事件函數
EventEmitter.prototype.emit=function(eventName, _) {
varevents=this.events[eventName],
args= Array.prototype.slice.call(arguments,1),
i,m;
if(!events) {
return;
}
for(i=0,m=events.length;i
events[i].apply(null,args);
}
}
在該事件對象中,定義了兩個方法on和emit,on作為事件的監聽函數,第一個參數是事件名稱,第二個參數是事件的回調函數;emit是觸發方法,其參數將作為回調函數中的參數。
這里我們任意定義一個對象:
const Obj=function(){
}
Obj.prototype=new EventEmitter()//繼承EventEmit
對象繼承EventEmit;
在button上綁定click事件,作為dom層的事件觸發,并在其中觸發自定義事件
const table=newTable();
document.querySelector("button").addEventListener("click",function(){ table.emit("addRow");})
在邏輯處理部分,監聽addRow事件,并定義回調函數:
functionTable(){
}
Table.prototype=newEventEmitter();
Table.prototype.on("addRow",function(){
console.log("addRow");
})
在dom層可以進行與頁面元素的相關操作,將頁面數據傳遞以事件觸發的形式傳遞給js的邏輯層,這樣一來實現了dom操作與邏輯的分離,代碼更加干凈。
目前大部分的業務邏輯都可以通過vue或者angular這樣的框架實現,單純的dom操作越來越少,但還是認為多多接觸一些模式與面向對象的知識可以加深我們對代碼的認識,加快學習速度,以上。
后記:
通篇寫下來,發現與觀察者模式有些相像,看來還是需要加強學習,以后我與會分享前端開發過程中的認識與感想;webRTC的相關知識也會記錄下來。
希望這篇分享對大家有所幫助!