標籤:cal ++ javascrip == move create event remove log
var Event = (function() { var global = this, Event, _default = ‘default‘; Event = function() { var _create, _listen, _trigger, _remove, _shift = Array.prototype.shift, _unshift = Array.prototype.unshift, namespaceCache = {}, each = function(ary, fn) { var ret; for (var i = 0, l = ary.length; i < l; i ++) { var n = ary[i]; ret = fn.call(n, i, n); }; return ret; }; _listen = function(key, fn, cache) { if (!cache[key]) { cache[key] = []; }; cache[key].push(fn); }; _trigger = function() { var cache = _shift.call(arguments), key = _shift.call(arguments), args = arguments, _self = this, stack = cache[key]; if (!stack || !stack.length) return; return each(stack, function() { return this.apply(_self, args); }); }; _remove = function(key, cache, fn) { if (cache[key]) { if (fn) { for (var i = cache[key].length; i >= 0; i--) { if (cache[key][i] === fn) { cache[key].splice(i, 1); }; }; } else { cache[key] = []; }; }; }; _create = function(namespace) { var namespace = namespace || _default; var cache = {}, offlineStack = [], ret = { listen: function(key, fn, last) { _listen(key, fn, cache); if (offlineStack === null) return; if (last === ‘last‘) { offlineStack.length && offlineStack.pop()(); } else { each(offlineStack, function() { this(); }); }; offlineStack = null; }, trigger: function() { var fn, args, _self = this; _unshift.call(arguments, cache); args = arguments; fn = function() { return _trigger.apply(_self, args); }; if (offlineStack) { return offlineStack.push(fn); }; return fn(); }, remove: function(key, fn) { _remove(key, cache, fn); }, one: function(key, fn, last) { _remove(key, cache); this.listen(key, fn, last); } }; return namespace ? (namespaceCache[namespace] ? namespaceCache[namespace] : namespaceCache[namespace] = ret) : ret; }; return { create: _create, one: function(key, fn, last) { var event = this.create(); event.one(key, fn, last); }, remove: function(key, fn) { var event = this.create(); event.remove(key, fn); }, listen: function(key, fn, last) { var event = this.create(); event.listen(key, fn, last); }, trigger: function() { var event = this.create(); event.trigger.apply(this, arguments); } }; }(); return Event; })();
使用姿勢:
/*// 先發布後訂閱 event.trigger(‘evt1‘, 1, 2); event.trigger(‘evt1‘, 3, 4); // 都存到offlineStack中去了 event.listen(‘evt1‘, e1); // 當有listen監聽時,遍曆offlineStack中的方法,發給第一次的listen event.listen(‘evt1‘, e2);*/ /*// 先訂閱後發布 event.listen(‘evt1‘, e1); event.listen(‘evt1‘, e2); // 先訂閱的事件都存到cache對象中去了 event.trigger(‘evt1‘, 1, 2); // 每次發布,都會遍曆cache對象中對象事件名的數組 event.trigger(‘evt1‘, 3, 4); */ /*// 先發布後訂閱 listen方法第三個參數可以是last,只有只會去多個trigger中的最後一個 event.trigger(‘evt1‘, 1, 2); // 1). event.trigger(‘evt1‘, 3, 4); // 2). 都存到offlineStack中去了 event.listen(‘evt1‘, e1, ‘last‘); // 只會收到2).這個trigger*/ /*// 先訂閱後發布再刪除然後再發布,會發現evt1事件對象的cache[key]數組中少了e1函數,所以 // 再次發布只有e2執行了 event.listen(‘evt1‘, e1); event.listen(‘evt1‘, e2); event.trigger(‘evt1‘, 1, 2); event.remove(‘evt1‘, e1); event.trigger(‘evt1‘, 3, 4);*/ // 訂閱的再多,也只使用一個訂閱 /*// 1). 先訂閱後發布 event.one(‘evt1‘, e1); event.one(‘evt1‘, e2); // 會使用這個,因為前一個被刪了 event.trigger(‘evt1‘, 11, 22); // 所以會執行兩次e2函數 event.trigger(‘evt1‘, 33, 44);*/ // 2). 先發布後訂閱 /*event.trigger(‘evt1‘, 11, 22); // 所以會執行兩次e2函數 event.trigger(‘evt1‘, 33, 44); event.one(‘evt1‘, e1); // 會使用這個,因為offlineStack被置為null了 event.one(‘evt1‘, e2); // 這個不執行了,需要等到下次trigger才會觸發,因為e1從cache中刪掉了,加入了e2, 如果後面還有one方法以此類推,會刪除上一個監聽的函數,添加新的監聽函數*/ // 3). 先發布後訂閱 one方法的第三個參數last會只接收最後一個trigger event.trigger(‘evt1‘, 11, 22); event.trigger(‘evt1‘, 33, 44); event.one(‘evt1‘, e2, ‘last‘); event.one(‘evt1‘, e1, ‘last‘);
JavaScript設計模式 - 訂閱發布模式(觀察者模式)