原文地址git
EventFire倉庫地址: github.com/ccforward/E… (求點進去加個Star)github
事件的管理主要有三點:綁定(on)、觸發(fire)、銷燬(off);因此寫一個自定義的事件庫就從這三點出發。數組
下面一步一步來寫函數
就像在各類js庫裏面監聽DOM事件同樣,會有下面幾種方式:ui
event.on('someEvent', callback)
// 綁定多個事件
event.on(['someEventA', 'someEventB'], callback)
// 綁定一次
event.once('someEvent', callback)
// .... 其餘複製代碼
PS: 觸發的函數名能夠是 trigger
或者 emmit
,我的感受 fire
像遊戲同樣,聽起來更爽。this
event.fire('someEvent')
// 觸發時綁定數據
event.fire('someEvent', {weapon: 'machine gun'})
// 觸發多個事件
event.fire(['someEventA', 'someEventB'], callback)
// .... 其餘複製代碼
銷燬確定和事件綁定是對應關係spa
event.off('someEvent', callback)
event.off('someEvent')
event.off(['someEventA', 'someEventB'], callback)
// .... 其餘複製代碼
一個簡單的事件庫應該有以下的方法:prototype
on
事件綁定once
綁定一次off
事件解綁fire
觸發事件offAll
解綁全部事件listeners
返回某一事件上的監聽器enable
事件綁定和觸發-可用disable
事件綁定和觸發-暫停destory
解綁實例上的事件,並徹底銷燬這個實例(不能再繼續綁定和觸發事件)最開始時已經有了兩個基本的用法,思考後想到一些新的傳參方式來支持更加靈活的事件綁定:設計
on('event', callback, {once: true})
on(['event1', 'event2'], callback, {once: true})
事件和回調的鍵值對code
on({
event1: function(){},
event2: function(){}
}, {once: true});複製代碼
綁定到全部事件上
on(function(){}, {once: true})複製代碼
函數監聽器的名字也應該能支持正則
on(/^event/)
on(/event\d+/)複製代碼
最後一個可選參數是考慮到 once
方法後來添加的,對於 on
方法直接單次的事件綁定會更靈活些
on
最後還應該返回 this
來支持鏈式調用
在 on
方法上添加了 {once: true}
這個可選參數後,這個方法就僅僅是 on
方法的一個變形了,再也不多說。
once
能夠和最後提到的 scope
統一放在配置項中
off
很好理解, 它設計確定和 on
是對應的,不過會多一種調用方式:
off('eventName')
解綁 eventName 事件
fire
也是和 on
相對應的:
參數 data 能夠用在回調函數中,用來傳遞狀態、自定義數據等消息
這裏須要建立三個內部變量,用來存儲回調函數,從而在解綁的時候可以找到已經綁定的函數
on(function(){})
因此解綁全部事件就是把上面三個變量置爲空
PS: 這個方法也可直接用在構造器中,初始化上面三個內部變量
listeners(eventName)
返回一個綁定在 eventName 上的全部函數的數組
這兩個方法最開始考慮叫 pause
和 goon
但只是個構思,後來看了其餘的事件庫後發現暫停綁定事件的執行是個很大的需求才改成更通用的名字
一樣這裏也須要引入一個內部變量 _enabled
來對應兩個方法設置爲 true
和 false
這個方法實現起來最簡單粗暴,三步:
null
或 false
Function.prototype
函數在綁定的時候能夠添加一個做用域,相似添加 {once: true}
同樣, 添加一個名爲 scope
的配置來替代 this
on('event1', fn1, {scope: {hello: 'world'}})
on('event2', fn2, {scope: {hello: 'world'}, once: true})複製代碼
fire
方法的最後一個參數 data
, 可是在 fire 的時候須要傳遞數據,所以一個 data 變量就是個剛需了。
e.on('event', function(ev){
console.log(ev.data)
});
e.fire('event', {a: 123});複製代碼
最後添加 commonjs 和 AMD 規範的兼容,具體的代碼在 index.js 最後