前端经常性会用到的addEventListener
和removeEventListener
,在这里使用class
进行一个简单的实现:
1. 实现分析
通过想象addEventListener
和removeEventListener
的功能,需要包含以下核心功能:
- 能够注册处理函数(handler function)
- 能够发布事件(emit event)
- 在发布事件的同时执行性已注册的处理函数,需要维护处理函数的事件的对应关系
- 能够移除处理函数
2. 代码实现
const noop = () => {};
export class EventDemo {
constructor({isCover}) {
this.__message__ = {};
this.isCover = isCover; // listener添加的模式是覆盖还是追赠
}
// 注册事件
addEventListener(type, fn = noop) {
let curEvent = this.__message__[type];
if (Object.prototype.toString.call(curEvent) === '[object Undefined]' || this.isCover) {
curEvent = [fn];
} else {
// 是否已经添加了相同的listener
if (!curEvent.includes(fn)) {
curEvent.push(fn);
}
}
this.__message__[type] = curEvent;
}
// 发布消息接口
emitEvent(type, args) {
// 当消息不存在时直接返回
if (!this.__message__[type]) {
return;
}
args = args || {};
// 依次执行消息对应的动作队列
for (let i = 0, len = this.__message__[type].length; i < len; i++) {
this.__message__[type][i].call(this, args);
}
}
// 移除事件监听的处理函数
removeEventListener(type, fn) {
if (this.__message__[type]) {
this.__message__[type] = this.__message__[type].filter(item => item !== fn);
if (this.__message__[type].length === 0) {
delete this.__message__[type];
}
}
}
// 清除特定的某一类监听事件
removeEventListenerAllByType(type) {
delete this.__message__[type];
}
// 清除所有监听事件
removeEventListenerAll() {
this.__message__ = {};
}
// 获取某一类型的listener
getEventListenerListByType(type) {
return this.__message__[type];
}
// 获取所有绑定listener的事件名称
getEventTypes() {
return Object.keys(this.__message__);
}
}
Demo 演示
定义一个Doggy
类继承自EventDemo
class Doggy extends EventDemo {
static EVENT_BARK = 'bark';
constructor(props) {
super(props)
this.name = props.name;
}
bark() {
console.log(`bark:${this.name}...汪汪汪`)
this.emitEvent(Doggy.EVENT_BARK, this)
}
}
const handleDoggyBark = (doggy) => {
console.log(`handleDoggyBark: 打 - 狗狗 ${doggy.name}`)
}
let doggy = new Doggy({name: '小强', isCover: true});
doggy.addEventListener(Doggy.EVENT_BARK, handleDoggyBark)
console.log('getEventListenerListByType: ', doggy.getEventListenerListByType(Doggy.EVENT_BARK))
console.log('getEventTypes: ', doggy.getEventTypes())
doggy.bark();
doggy.removeEventListener(Doggy.EVENT_BARK, handleDoggyBark)
console.log('[after remove] getEventListenerListByType: ', doggy.getEventListenerListByType(Doggy.EVENT_BARK))
console.log('[after remove] getEventTypes: ', doggy.getEventTypes())
输出结果如下图所示: