原生 JS 实现全局发布订阅事件
1 var Event = (function() { 2 var global = this, 3 Event, 4 _default = 'default'; 5 Event = function() { 6 var _listen, 7 _trigger, 8 _remove, 9 _slice = Array.prototype.slice, 10 _shift = Array.prototype.shift, 11 _unshift = Array.prototype.unshift, 12 namespaceCache = {}, 13 _create, 14 find, 15 each = function(ary, fn) { 16 var ret; 17 for (var i = 0, l = ary.length; i < l; i++) { 18 var n = ary[i]; 19 ret = fn.call(n, i, n); 20 } 21 return ret; 22 }; 23 24 _listen = function(key, fn, cache) { 25 if (!cache[key]) { 26 cache[key] = [] 27 } 28 cache[key].push(fn) 29 }; 30 _remove = function(key, cache, fn) { 31 if (cache[key]) { 32 if (fn) { 33 for (var i = cache[key].length; i >= 0; i--) { 34 if (cache[key][i] === fn) { 35 cache[key].splice(i, 1); 36 } 37 } 38 } 39 } else { 40 cache[key] = [] 41 } 42 }; 43 _trigger = function() { 44 var cache = _shift.call(arguments), 45 key = _shift.call(arguments), 46 args = arguments, 47 _self = this, 48 ret, 49 stack = cache[key]; 50 51 if (!stack || !stack.length) { 52 return 53 } 54 return each(stack, function() { 55 return this.apply(_self, args); 56 }); 57 }; 58 _create = function(namespace) { 59 var namespace = namespace || _default; 60 var cache = {}, 61 offineStack = [], //离线事件 62 ret = { 63 listen: function(key, fn, last) { 64 _listen(key, fn, cache); 65 if (offineStack === null) { 66 return; 67 } 68 if (last === 'last') { 69 offineStack.length && offineStack.pop(); 70 } else { 71 each(offineStack, function() { 72 this() 73 }); 74 } 75 offineStack = null 76 }, 77 one: function(key, fn, last) { 78 _remove(key, cache); 79 this.listen(key, fn, last) 80 }, 81 remove: function(key, fn) { 82 _remove(key, cache, fn); 83 }, 84 trigger: function() { 85 var fn, 86 args, 87 _self = this; 88 89 _unshift.call(arguments, cache); 90 args = arguments; 91 fn = function() { 92 return _trigger.apply(_self, args); 93 }; 94 if (offineStack) { 95 return offineStack.push(fn); 96 } 97 return fn() 98 } 99 }; 100 return namespace ? 101 (namespaceCache[namespace] ? namespaceCache[namespace] : 102 namespaceCache[namespace] = ret) : ret; 103 }; 104 return { 105 create: _create, 106 one: function(key, fn, last) { 107 var event = this.create(); 108 event.one(key, fn, last); 109 }, 110 remove: function(key, fn) { 111 var event = this.create(); 112 event.remove(key, fn); 113 }, 114 listen: function(key, fn, last) { 115 var event = this.create(); 116 event.listen(key, fn, last); 117 }, 118 trigger: function() { 119 var event = this.create(); 120 event.trigger.apply(this, arguments); 121 } 122 }; 123 }(); 124 return Event 125 })();