javascript实现在倒计时线程注册多个事件的功能
javascript实现倒计时的功能,相信很多朋友都做过,直接用setInterval不就行了。但是如果一个应用内有很多地方需要使用倒计时的功能,那不封装一下真的就不行了,至少一个应用内只要一个倒计时的线程在跑就OK了。
公司最近搞的一个项目,就大量使用了倒计时功能。比如有一个抢购功能,可以先预约,到点后系统就会给出通知,然后就能抢购商品。页面上要实现倒计时的显示,按钮的切换。demo地址:http://www.01happy.com/demo/javascript-countdown/
代码可以在demo里通过查看源码看到,这里说明下javascript代码
1.事件类
//事件类 var EventObject = { createNew: function() { var eventObject = {}; /** * 事件执行时间 */ eventObject.excuteTime = 0; /** * 事件执行方法 * @param {int} timestamp * @returns */ eventObject.excute = function(timestamp) { }; return eventObject; } };
我们把要执行的任务理解成一个一个的事件,比如到点切换按钮为立即抢购也可以当成一个事件。每个事件都可以设定执行的事件和执行的方法体。
2.倒计时类
/** * 倒计时类 */ var TimeThreading = { createNew: function() { var timeThreading = {}; /** * setInterval返回ID */ timeThreading.t = {}; /** * 注册要执行的事件 */ timeThreading.eventObjects = new Array(); /** * 开始执行 * @returns {undefined} */ timeThreading.start = function() { var self = this; this.t = setInterval(function() { //获取当期时间戳 var timestamp = Math.ceil((new Date().getTime()) / 1000); var eventObjects = self.getEventObjects(); for (var i in eventObjects) { if (!eventObjects[i].excuteTime) {//如果没有设定执行时间,则直接执行事件 setTimeout(eventObjects[i].excute(timestamp), 1000); } else {//有设定执行时间,则校验当前时间和事件执行时间是否匹配 if (eventObjects[i].excuteTime === timestamp) { setTimeout(eventObjects[i].excute(timestamp), 1000); //事件执行后,则移除该事件。这里并没有考虑事件执行成功与否 self.removeEvent(i); } } } }, 1000); }; /** * 结束执行 */ timeThreading.end = function() { clearInterval(this.t); }; /** * 注册事件 * @param {type} eventObject * @returns {TimeThreading} */ timeThreading.registerEvent = function(eventObject) { this.eventObjects.push(eventObject); return this; }; /** * 移除事件 * @param {type} eventObject * @returns {TimeThreading} */ timeThreading.removeEvent = function(index) { this.getEventObjects().splice(index, 1); return this; }; /** * 获取所有注册的事件 * @returns {Array} */ timeThreading.getEventObjects = function() { return this.eventObjects; }; return timeThreading; } };
单独跑的一个线程,通过start、end方法控制倒计时的运行和停止;通过registerEvent来注册要执行的事件;代码中注释比较详细了,不多做说明,值得一提的是执行每个事件的时候除了直接调用事件的excute的方法,更在外围加了setTimeout。
3. 运行示例
//当前时间戳 var timestamp = Math.ceil((new Date().getTime()) / 1000); //实例化倒计时线程 var timeThreading = TimeThreading.createNew(); //注册时间戳显示事件 var eventObject = EventObject.createNew(); eventObject.excute = function(timestamp) { document.getElementById('show-timestamp').innerHTML = timestamp; }; timeThreading.registerEvent(eventObject); //注册按钮切换到即将开始事件 var willBeginEvent = EventObject.createNew(); willBeginEvent.excuteTime = timestamp + 5; willBeginEvent.excute = function() { document.getElementById('status-btn').innerHTML = "即将开始"; }; timeThreading.registerEvent(willBeginEvent); //注册按钮切换到立即抢购事件 var snapUpEvent = EventObject.createNew(); var timestamp = Math.ceil((new Date().getTime()) / 1000); snapUpEvent.excuteTime = timestamp + 10; snapUpEvent.excute = function() { document.getElementById('status-btn').innerHTML = "立即抢购"; }; timeThreading.registerEvent(snapUpEvent); //注册按钮切换到已经结束事件 var endEvent = EventObject.createNew(); endEvent.excuteTime = timestamp + 15; endEvent.excute = function() { document.getElementById('status-btn').innerHTML = "已经结束"; }; timeThreading.registerEvent(endEvent); //开始倒计时 timeThreading.start();
小结
自己对javascript研究的并不深透,只是用javascript实现了这样的一个思路:一个应用内只跑一个倒计时线程,而后把要执行的事件注册到该线程上,从而实现较好的代码分离效果。
原文链接: http://www.01happy.com/javascript-events-registered-in-the-countdown-thread-function/