/*
* 示例:
* Event.create("namespace1").listen('click', function(a){
* console.log(a);
* });
* Event.create("namespace1").trigger("click", 1);
*/
window.myEvent = (function() {
var global = this,
Event,
_default = 'default';
Event = function() {
var _listen,
_trigger,
_remove,
_slice = Array.prototype.slice,
_shift = Array.prototype.shift,
_unshift = Array.prototype.unshift,
namespaceCache = [],
_create,
find,
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);
};
// 移除订阅
_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] = [];
}
}
};
// 发布
_trigger = function() {
var cache = _shift.call(arguments),
key = _shift.call(arguments),
args = arguments,
_self = this,
ret,
stack = cache[key];
if(!stack || !stack.length) {
return;
}
return each(stack, function() {
return this.apply(_self, args);
});
};
// 创建命名空间
_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;
},
one: function (key, fn, last) {
_remove(key, cache);
this.listen(key, fn, last);
},
remove: function(key, fn, last) {
_remove(key, cache, fn);
},
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();
}
};
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;
})();