写一个简单的支持Node.js&浏览器的自定义事件库

原文地址

自定义事件库 EventFire

源码

EventFire仓库地址: github.com/ccforward/E… (求点进去加个Star)

事件的管理主要有三点:绑定(on)、触发(fire)、销毁(off);所以写一个自定义的事件库就从这三点出发。

下面一步一步来写

0、思考

绑定

就像在各种js库里面监听DOM事件一样,会有下面几种方式:

event.on('someEvent', callback)
// 绑定多个事件
event.on(['someEventA', 'someEventB'], callback)
// 绑定一次
event.once('someEvent', callback)
// ....  其他复制代码
触发

PS: 触发的函数名可以是 trigger 或者 emmit,个人感觉 fire 像游戏一样,听起来更爽。

event.fire('someEvent')
// 触发时绑定数据
event.fire('someEvent', {weapon: 'machine gun'})
// 触发多个事件
event.fire(['someEventA', 'someEventB'], callback)

// ....  其他复制代码
销毁

销毁肯定和事件绑定是对应关系

event.off('someEvent', callback)
event.off('someEvent')
event.off(['someEventA', 'someEventB'], callback)

// ....  其他复制代码

1、方法设计

一个简单的事件库应该有如下的方法:

  • on 事件绑定
  • once 绑定一次
  • off 事件解绑
  • fire 触发事件
  • offAll 解绑所有事件
  • listeners 返回某一事件上的监听器
  • enable 事件绑定和触发-可用
    disable 事件绑定和触发-暂停
  • destory 解绑实例上的事件,并完全销毁这个实例(不能再继续绑定和触发事件)

2、方法细节

on 方法

最开始时已经有了两个基本的用法,思考后想到一些新的传参方式来支持更加灵活的事件绑定:

  • 字符串参数,单个事件
    on('event', callback, {once: true})
  • 数组参数,事件集合
    on(['event1', 'event2'], callback, {once: true})
  • 事件和回调的键值对

    on({
      event1: function(){},
      event2: function(){}
    }, {once: true});复制代码
  • 绑定到所有事件上

    on(function(){}, {once: true})复制代码
  • 函数监听器的名字也应该能支持正则

    on(/^event/)
    on(/event\d+/)复制代码

最后一个可选参数是考虑到 once 方法后来添加的,对于 on 方法直接单次的事件绑定会更灵活些

on 最后还应该返回 this 来支持链式调用

once 方法

on 方法上添加了 {once: true} 这个可选参数后,这个方法就仅仅是 on 方法的一个变形了,不再多说。

once 可以和最后提到的 scope 统一放在配置项中

off 方法

off 很好理解, 它设计肯定和 on 是对应的,不过会多一种调用方式:

off('eventName') 解绑 eventName 事件

fire 方法

fire 也是和 on 相对应的:

  • fire('event');
  • fire('event', data);
  • fire(['event1', 'event2']);
  • fire(['event1', 'event2'], data);
  • fire({event1: data, event2: data});

参数 data 可以用在回调函数中,用来传递状态、自定义数据等消息

offAll 方法

这里需要创建三个内部变量,用来存储回调函数,从而在解绑的时候能够找到已经绑定的函数

  • _handlers 存储绑定的监听器回调函数的键值对
  • _handlersAll 存储绑定的在所有事件对象上的监听器数组
    就是这种 on(function(){})
  • _handlersRegx 存储通过正则方式绑定的监听器以及正则pattern

所以解绑所有事件就是把上面三个变量置为空

PS: 这个方法也可直接用在构造器中,初始化上面三个内部变量

listeners 方法

listeners(eventName) 返回一个绑定在 eventName 上的所有函数的数组

enable disabled 方法

这两个方法最开始考虑叫 pausegoon 但只是个构思,后来看了其他的事件库后发现暂停绑定事件的执行是个很大的需求才改为更通用的名字

同样这里也需要引入一个内部变量 _enabled 来对应两个方法设置为 truefalse

destory 方法

这个方法实现起来最简单粗暴,三步:

  1. offAll() 解绑
  2. 把所有内部变量设为 nullfalse
  3. 上面所有方法设为空函数,也就是 Function.prototype

3、其他

作用域

函数在绑定的时候可以添加一个作用域,类似添加 {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 最后

转载于:https://juejin.im/post/57bc1c26165abd00662f251e

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值