简体   繁体   English

实时倒数时钟

[英]Live countdown clock

Basically, I am generating a computer based test and obviously I want to be presenting the timeleft in the exam for the examinee and when the countdown reaches zero submit the test. 基本上,我正在生成一个基于计算机的测试,并且显然我想在考试中为应试者提供剩余的时间,并且当倒数达到零时提交测试。

I have the duration stored as time() in my MySQL database with other details of the test etc. 我将持续时间作为time()与其他测试详细信息一起存储在我的MySQL数据库中。

My question is regarding the best method for my live countdown timer. 我的问题是关于实时倒数计时器的最佳方法。 I am struggling to work out how I would do it so that if the student clicked to refresh the page the clock wouldnt reset. 我正在努力研究如何做,以便如果学生单击刷新页面,时钟将不会重置。

any information would help. 任何信息都会有所帮助。

thanks, 谢谢,

I assume you store the test details in the database (so you can mark which questions are answered etc). 我假设您将测试详细信息存储在数据库中(以便您可以标记回答了哪些问题,等等)。 If you created a table which stores the testID and the startTime, you can have it so every time the page loads, it checks when the test was started, and starts the timer based on that value 如果您创建了一个存储testID和startTime的表,则可以让它在每次页面加载时检查启动测试的时间,并根据该值启动计时器

Table

id | studentId | testId | startTime
------------------------------------
1  | 1         | 1      | 1303214136

PHP PHP

    //Time left in seconds
    $timeLeft = time() - $startTime;

And then pass that $timeLeft variable to Javascript to start the timer 然后将该$ timeLeft变量传递给Javascript以启动计时器

I'd make an AJAX call and get the timestamp of the date of the exam and then run a Javascript based countdown which take the actual time and subtract the exam time in order to get the time needed. 我会打电话给AJAX并获取考试日期的时间戳,然后运行基于Java的倒计时,该计时将花费实际时间并减去考试时间以获得所需的时间。

PHP based script will only work once since the PHP script is run once and then the page, once loaded, it static. 基于PHP的脚本仅可运行一次,因为该PHP脚本将运行一次,然后页面一旦加载便是静态的。

References: 参考文献:

In Javascript you can define TimeOuts and Intervals . 在Javascript中,您可以定义TimeOutsIntervals

Basically, a TimeOut is a countdown before doing an action: 基本上,超时是在执行操作之前的倒计时:

setTimeout ( expression, timeout );

And an interval is a repeated action: 间隔是重复的动作:

setInterval ( expression, interval );

So, in your case, you can set an Interval every minutes to check, with an ajax call, the time left. 因此,根据您的情况,您可以每隔一分钟设置一个时间间隔,通过ajax调用来检查剩余时间。

More information in this good article: http://www.elated.com/articles/javascript-timers-with-settimeout-and-setinterval/ 这篇好文章中的更多信息: http : //www.elated.com/articles/javascript-timers-with-settimeout-and-setinterval/

You should store the time on the server and do not rely on the client code - it should only display the time but not really control the test duration. 您应该将时间存储在服务器上,而不要依赖于客户端代码-它应该仅显示时间,而不能真正控制测试时间。

For example, you can store requesting time in the session and then calculate difference between the current time and the saved time. 例如,您可以在会话中存储请求时间,然后计算当前时间与保存的时间之间的时差。

created a stopwatch/countdown a few days ago, find working example here: http://jsfiddle.net/ezmilhouse/V2S9d/ 几天前创建了秒表/倒计时,请在此处找到工作示例: http : //jsfiddle.net/ezmilhouse/V2S9d/

/*

JQUERY: STOPWATCH & COUNTDOWN

This is a basic stopwatch & countdown plugin to run with jquery. Start timer, pause it, stop it or reset it. Same behaviour with the countdown besides you need to input the countdown value in seconds first. At the end of the countdown a callback function is invoked.

Any questions, suggestions? marc.fuehnen(at)gmail.com

*/

$(document).ready(function() {

    (function($){

        $.extend({

            APP : {                

                formatTimer : function(a) {
                    if (a < 10) {
                        a = '0' + a;
                    }                              
                    return a;
                },    

                startTimer : function(dir) {

                    var a;

                    // save type
                    $.APP.dir = dir;

                    // get current date
                    $.APP.d1 = new Date();

                    switch($.APP.state) {

                        case 'pause' :

                            // resume timer
                            // get current timestamp (for calculations) and
                            // substract time difference between pause and now
                            $.APP.t1 = $.APP.d1.getTime() - $.APP.td;                            

                        break;

                        default :

                            // get current timestamp (for calculations)
                            $.APP.t1 = $.APP.d1.getTime(); 

                            // if countdown add ms based on seconds in textfield
                            if ($.APP.dir === 'cd') {
                                $.APP.t1 += parseInt($('#cd_seconds').val())*1000;
                            }    

                        break;

                    }                                   

                    // reset state
                    $.APP.state = 'alive';   
                    $('#' + $.APP.dir + '_status').html('Running');

                    // start loop
                    $.APP.loopTimer();

                },

                pauseTimer : function() {

                    // save timestamp of pause
                    $.APP.dp = new Date();
                    $.APP.tp = $.APP.dp.getTime();

                    // save elapsed time (until pause)
                    $.APP.td = $.APP.tp - $.APP.t1;

                    // change button value
                    $('#' + $.APP.dir + '_start').val('Resume');

                    // set state
                    $.APP.state = 'pause';
                    $('#' + $.APP.dir + '_status').html('Paused');

                },

                stopTimer : function() {

                    // change button value
                    $('#' + $.APP.dir + '_start').val('Restart');                    

                    // set state
                    $.APP.state = 'stop';
                    $('#' + $.APP.dir + '_status').html('Stopped');

                },

                resetTimer : function() {

                    // reset display
                    $('#' + $.APP.dir + '_ms,#' + $.APP.dir + '_s,#' + $.APP.dir + '_m,#' + $.APP.dir + '_h').html('00');                 

                    // change button value
                    $('#' + $.APP.dir + '_start').val('Start');                    

                    // set state
                    $.APP.state = 'reset';  
                    $('#' + $.APP.dir + '_status').html('Reset & Idle again');

                },

                endTimer : function(callback) {

                    // change button value
                    $('#' + $.APP.dir + '_start').val('Restart');

                    // set state
                    $.APP.state = 'end';

                    // invoke callback
                    if (typeof callback === 'function') {
                        callback();
                    }    

                },    

                loopTimer : function() {

                    var td;
                    var d2,t2;

                    var ms = 0;
                    var s  = 0;
                    var m  = 0;
                    var h  = 0;

                    if ($.APP.state === 'alive') {

                        // get current date and convert it into 
                        // timestamp for calculations
                        d2 = new Date();
                        t2 = d2.getTime();   

                        // calculate time difference between
                        // initial and current timestamp
                        if ($.APP.dir === 'sw') {
                            td = t2 - $.APP.t1;
                        // reversed if countdown
                        } else {
                            td = $.APP.t1 - t2;
                            if (td <= 0) {
                                // if time difference is 0 end countdown
                                $.APP.endTimer(function(){
                                    $.APP.resetTimer();
                                    $('#' + $.APP.dir + '_status').html('Ended & Reset');
                                });
                            }    
                        }    

                        // calculate milliseconds
                        ms = td%1000;
                        if (ms < 1) {
                            ms = 0;
                        } else {    
                            // calculate seconds
                            s = (td-ms)/1000;
                            if (s < 1) {
                                s = 0;
                            } else {
                                // calculate minutes   
                                var m = (s-(s%60))/60;
                                if (m < 1) {
                                    m = 0;
                                } else {
                                    // calculate hours
                                    var h = (m-(m%60))/60;
                                    if (h < 1) {
                                        h = 0;
                                    }                             
                                }    
                            }
                        }

                        // substract elapsed minutes & hours
                        ms = Math.round(ms/100);
                        s  = s-(m*60);
                        m  = m-(h*60);                                

                        // update display
                        $('#' + $.APP.dir + '_ms').html($.APP.formatTimer(ms));
                        $('#' + $.APP.dir + '_s').html($.APP.formatTimer(s));
                        $('#' + $.APP.dir + '_m').html($.APP.formatTimer(m));
                        $('#' + $.APP.dir + '_h').html($.APP.formatTimer(h));

                        // loop
                        $.APP.t = setTimeout($.APP.loopTimer,1);

                    } else {

                        // kill loop
                        clearTimeout($.APP.t);
                        return true;

                    }  

                }

            }    

        });

        $('#sw_start').live('click', function() {
            $.APP.startTimer('sw');
        });    

        $('#cd_start').live('click', function() {
            $.APP.startTimer('cd');
        });           

        $('#sw_stop,#cd_stop').live('click', function() {
            $.APP.stopTimer();
        });

        $('#sw_reset,#cd_reset').live('click', function() {
            $.APP.resetTimer();
        });  

        $('#sw_pause,#cd_pause').live('click', function() {
            $.APP.pauseTimer();
        });                

    })(jQuery);

}); });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM