zhh.event.js
(function() {
/**
// 事件, zhaohuihua, 2015-04-11
// var event = zhh.event.create();
// event.on("xxx", fn);
// event.off("xxx", fn);
// event.trigger([once=true], "ready", args 1, ..., args n);
// event.trigger("xxx", args 1, ..., args n);
// once, 某些事件只会触发一次, 如init,ready之类, 先触发后注册也要得到回调
// @example
// Service
var UserService = (function(zhh) {
var event = zhh.event.create();
// 触发ready事件once=true
event.trigger(true, "ready", new Date().getTime());
var login = function(data) {
...
event.trigger("change", newUser);
...
};
var edit = function(data) {
...
event.trigger("change", newUser, oldUser);
...
};
return {
login:login, edit:edit,
on:zhh.event.bind(event)
}
})(zhh);
// Controller
var AccountCtrl = (function(UserService) {
UserService.on("ready", function() {
...
});
UserService.on("change", function(newUser, oldUser) {
console.log("user change");
console.log(oldUser);
console.log(newUser);
...
});
...
})(UserService);
*/
var Event = function() {};
// 注册监听器
Event.prototype.on = function(key, fn) {
if (typeof(fn) !== "function") {
return;
}
// 注册监听器
if (this[key]) {
this[key].push(fn);
} else {
this[key] = [fn];
}
// 注册前已经触发过了, 直接回调
var triggered = this["__" + key + "__"];
if (triggered) {
window.setTimeout(function() {
fn.apply(fn, triggered);
}, 1);
}
};
// 移除监听器
Event.prototype.off = function(key, fn) {
if (this[key]) {
if (!fn) {
delete this[key];
} else {
var list = this[key];
var index = list.indexOf(fn);
while (index >= 0) {
list.splice(index, 1);
index = list.indexOf(fn);
}
}
}
};
// 触发事件
// event.trigger(true, "ready", args);
// event.trigger("xxx", args);
// once, 某些事件如init,ready之类, 只会触发一次
// 这类事件先触发后注册也要得到回调
Event.prototype.trigger = function(once, key) {
var args;
if (typeof(once) == "string") {
args = Array.prototype.splice.call(arguments, 1);
key = once; once = false;
} else {
args = Array.prototype.splice.call(arguments, 2);
}
var me = this;
// 如果once事件已经触发过了就不再触发
if (me["__" + key + "__"]) { return; }
window.setTimeout(function() {
// 记录已经触发的参数
// 用于init,ready之类只会触发一次的事件, 先触发后注册也能得到回调
if (once) { me["__" + key + "__"] = args; }
// 逐一回调监听器
var list = me[key] || [];
for (var i = 0; i < list.length; i++) {
list[i].apply(list[i], args);
}
}, 1);
};
if (!window.zhh) { window.zhh = {}; }
window.zhh.event = {
create: function() { return new Event(); },
bind: function(e) { return function(key, fn) { e.on(key, fn); } }
};
})();
test.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta charset="utf-8">
<title> Event Test </title>
<style> body { font-size:14px; font-family: "Microsoft YaHei"; } </style>
<script src="zhh.event.js"></script>
</head>
<body>
<script>
(function() {
var log = function(msg) {
var div = document.createElement("div");
div.innerHTML = msg.replace("\t", " ").replace("\n", "<br>");
document.body.appendChild(div);
};
log("xxx id=888 有4处注册: A A B C");
log("xxx id=999 有2处注册: B C, A已经被off掉了");
log("init ready 可以先触发,后注册");
log("-----------------------------");
var event = zhh.event.create();
event.on("init", function() {
log("catched init");
});
event.on("ready", function(time) {
log("catched ready, time = " + time);
});
var logXxx = function(id, user, array) {
log("\tid="+id+"\tuser="+JSON.stringify(user)+"\tarray="+JSON.stringify(array));
};
var onXxx = function() {
log("A catched xxx");
logXxx.apply(logXxx, arguments);
};
event.on("xxx", onXxx);
event.on("xxx", onXxx);
event.on("xxx", function() {
log("B catched xxx");
logXxx.apply(logXxx, arguments);
});
event.on("xxx", function() {
log("C catched xxx");
logXxx.apply(logXxx, arguments);
});
event.trigger(true, "init");
event.trigger(true, "ready", new Date().getTime());
event.trigger("xxx", 888, { name:"zhaohuihua", phone:"139xxxx1382" }, [1,2,3,4,5]);
window.setTimeout(function() {
event.off("xxx", onXxx);
event.trigger("xxx", 999, { name:"stephen", phone:"139xxxx0000" }, [10,20,30,40,50]);
}, 10);
window.setTimeout(function() {
event.on("init", function() {
// 这里会执行, 因为init是once事件
log("catched init, 触发后注册");
});
event.on("ready", function(time) {
// 这里会执行, 因为ready是once事件
log("catched ready, 触发后注册, time = " + time);
});
event.on("xxx", function(time) {
// 这里不会执行, 因为xxx不是once事件
log("catched xxx, 触发后注册, time = " + time);
});
}, 100);
})();
</script>
</body>
</html>