原文地址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 最后