发布就是触发事件,例如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;
-
- }
-
- };