最新消息:yaf表单扩展中新增加了浮点数、日期和集合的校验。php yaf框架扩展实践三——表单

javascript实现在倒计时线程注册多个事件的功能

编程开发 138712浏览 0评论

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实现了这样的一个思路:一个应用内只跑一个倒计时线程,而后把要执行的事件注册到该线程上,从而实现较好的代码分离效果。

欢迎大家吐槽。

转载请注明:快乐编程 » javascript实现在倒计时线程注册多个事件的功能

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址