发布订阅代码
发布就是触发事件,例如node中的emitter.emit ,订阅就是绑定那个事件比如emitter.on。在jq中on绑定clink事件,就是类似订阅,当click就是发布了。
自己怎么实现呢,就是把订阅的事件,比如a,b两个事件,保存在一个对象中,当发布时,取是保存了事件,执行。
class PubSub {
constructor() {
this.handlers = {};
}
on(eventType, handler) {
//订阅
if (!(eventType in this.handlers)) {
this.handlers[eventType] = [];
}
this.handlers[eventType].push(handler);
}
emit(eventType, ...args) {
//发布
for (let i = 0; i < this.handlers[eventType].length; i++) {
this.handlers[eventType][i].apply(this, args);
}
return this;
}
}
var pubsub = new PubSub();
pubsub.on('A',function(data){
console.log(1 + data); // 执行第一个回调业务函数
});
pubsub.on('A',function(data){
console.log(2 + data); // 执行第二个业务回调函数
});
// 触发事件A
pubsub.emit('A',"我是参数");
在浏览器中的实现
function DefineEvent(element) {
this.init(element);
}
DefineEvent.prototype = {
constructor: DefineEvent,
init: function(element) {
this.element = (element && element.nodeType == 1) ? element : document;
return this;
},
/*
* 添加监听事件 * @param {string} type 监听的事件类型
* @param {Function} callback 回调函数
*/
addEvent: function(type,callback) {
var self = this;
if(self.element.addEventListener) { // 标准浏览器下
self.element.addEventListener(type,callback,false);
}else if(self.element.attachEvent){ // IE
if(isNaN(self.element[type])) {
self.element[type] = 0;
}
var fun = function(evt){
evt = evt ? evt : window.event;
if(evt.propertyName == type) {
callback.call(self.element);
}
}
self.element.attachEvent('onpropertychange',fun);
// 在元素上存储绑定回调,方便移除事件绑定
if(!self.element['callback' + callback]) {
self.element['callback' + callback] = fun;
}
}else {
self.element.attachEvent('on' + type,callback);
}
return self;
},
/*
* 移除事件
* @param {string} type 监听的事件类型
* @param {Function} callback 回调函数
*/
removeEvent: function(type,callback){
var self = this;
if(self.element.removeEventListener) {
self.element.removeEventListener(type,callback,false);
}else if(self.element.detachEvent) {
// 移除对应的自定义属性监听
self.element.detachEvent('onpropertychange',self.element['callback' + callback]);
// 删除储存在 DOM 上的自定义事件的回调
self.element['callback' + callback] = null;
}else {
self.element.detachEvent('on' + type,callback);
}
return self;
},
/*
* 触发事件
* @param {String} type 触发事件的类型
* @return {object} 返回的对象
*/
triggerEvent: function(type){
var self = this;
if(self.element.dispatchEvent) { // 标准浏览器下
// 创建事件
var evt = document.createEvent('Event');
// 定义事件的类型
evt.initEvent(type,true,true);
// 触发事件
self.element.dispatchEvent(evt);
}else if(self.element.fireEvent) { // IE
self.element[type]++;
}
return self;
}
};