事件工具:监听/触发

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>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值