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.
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
Table
id | studentId | testId | startTime
------------------------------------
1 | 1 | 1 | 1303214136
PHP
//Time left in seconds
$timeLeft = time() - $startTime;
And then pass that $timeLeft variable to Javascript to start the timer
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.
PHP based script will only work once since the PHP script is run once and then the page, once loaded, it static.
References:
- jQuery.ajax()
- AJAX reference on jQuery
- Countdown sample
In Javascript you can define TimeOuts
and Intervals
.
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.
More information in this good article: 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/
/*
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);
});
精彩评论