简单实现EventBus
我们知道,基于DOM2级绑定事件是基于事件池的机制,可以给同一个元素的同一个行为绑定多个不同的方法,当该行为触发时,绑定的这些方法会被依次执行。但是,DOM2级事件绑定只能对元素的默认行为进行方法绑定,例如:click、keydown、scroll等原生默认行为。
// 基于事件池机制实现事件绑定,可以绑定任意自定义事件
(function(){
function Sub(){
this.listeners = {}
}
Sub.prototype = {
// 原型重定向时记得手动补上 constructor
constructor: Sub,
on(type, fn){
// 绑定事件的时先判断该类型的事件是否已经存在
if(!this.listeners[type]) {
this.listeners[type] = [];
this.listeners[type].push(fn);
} else {
// 如果事件类型已经存在,在添加方法之前先判断该方法是否也已经存在(去重处理)
this.listeners[type].indexOf(fn) === -1 ? this.listeners[type].push(fn): null;
}
},
off(type, fn){
if(!this.listeners[type]) return;
// var index = this.listeners[type].indexOf(fn);
// splice 会改变原数组 =>“数组塌陷”
// index > -1 ? this.listeners[type].splice(index, 1) : null;
// 使用 filter,不会改变原始数组 =>解决数组塌陷问题
this.listeners[type] = this.listeners[type].filter(item=> item !== fn);
},
fire(type, ...parma){
// 通知方法执行时,得先看看是否有可执行的方法
if(!this.listeners[type]) return;
this.listeners[type].forEach(item => {
typeof item === 'function' ? item(...parma) : null
})
}
};
// 记得暴露出去
window.Sub = Sub;
})();