I have two demos, one with jQuery
and one without. Neither use date functions and are about as simple as it gets.
function startTimer(duration, display) {_x000D_
var timer = duration, minutes, seconds;_x000D_
setInterval(function () {_x000D_
minutes = parseInt(timer / 60, 10);_x000D_
seconds = parseInt(timer % 60, 10);_x000D_
_x000D_
minutes = minutes < 10 ? "0" + minutes : minutes;_x000D_
seconds = seconds < 10 ? "0" + seconds : seconds;_x000D_
_x000D_
display.textContent = minutes + ":" + seconds;_x000D_
_x000D_
if (--timer < 0) {_x000D_
timer = duration;_x000D_
}_x000D_
}, 1000);_x000D_
}_x000D_
_x000D_
window.onload = function () {_x000D_
var fiveMinutes = 60 * 5,_x000D_
display = document.querySelector('#time');_x000D_
startTimer(fiveMinutes, display);_x000D_
};
_x000D_
<body>_x000D_
<div>Registration closes in <span id="time">05:00</span> minutes!</div>_x000D_
</body>
_x000D_
function startTimer(duration, display) {
var timer = duration, minutes, seconds;
setInterval(function () {
minutes = parseInt(timer / 60, 10);
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.text(minutes + ":" + seconds);
if (--timer < 0) {
timer = duration;
}
}, 1000);
}
jQuery(function ($) {
var fiveMinutes = 60 * 5,
display = $('#time');
startTimer(fiveMinutes, display);
});
However if you want a more accurate timer that is only slightly more complicated:
function startTimer(duration, display) {_x000D_
var start = Date.now(),_x000D_
diff,_x000D_
minutes,_x000D_
seconds;_x000D_
function timer() {_x000D_
// get the number of seconds that have elapsed since _x000D_
// startTimer() was called_x000D_
diff = duration - (((Date.now() - start) / 1000) | 0);_x000D_
_x000D_
// does the same job as parseInt truncates the float_x000D_
minutes = (diff / 60) | 0;_x000D_
seconds = (diff % 60) | 0;_x000D_
_x000D_
minutes = minutes < 10 ? "0" + minutes : minutes;_x000D_
seconds = seconds < 10 ? "0" + seconds : seconds;_x000D_
_x000D_
display.textContent = minutes + ":" + seconds; _x000D_
_x000D_
if (diff <= 0) {_x000D_
// add one second so that the count down starts at the full duration_x000D_
// example 05:00 not 04:59_x000D_
start = Date.now() + 1000;_x000D_
}_x000D_
};_x000D_
// we don't want to wait a full second before the timer starts_x000D_
timer();_x000D_
setInterval(timer, 1000);_x000D_
}_x000D_
_x000D_
window.onload = function () {_x000D_
var fiveMinutes = 60 * 5,_x000D_
display = document.querySelector('#time');_x000D_
startTimer(fiveMinutes, display);_x000D_
};
_x000D_
<body>_x000D_
<div>Registration closes in <span id="time"></span> minutes!</div>_x000D_
</body>
_x000D_
Now that we have made a few pretty simple timers we can start to think about re-usability and separating concerns. We can do this by asking "what should a count down timer do?"
So with these things in mind lets write a better (but still very simple) CountDownTimer
function CountDownTimer(duration, granularity) {
this.duration = duration;
this.granularity = granularity || 1000;
this.tickFtns = [];
this.running = false;
}
CountDownTimer.prototype.start = function() {
if (this.running) {
return;
}
this.running = true;
var start = Date.now(),
that = this,
diff, obj;
(function timer() {
diff = that.duration - (((Date.now() - start) / 1000) | 0);
if (diff > 0) {
setTimeout(timer, that.granularity);
} else {
diff = 0;
that.running = false;
}
obj = CountDownTimer.parse(diff);
that.tickFtns.forEach(function(ftn) {
ftn.call(this, obj.minutes, obj.seconds);
}, that);
}());
};
CountDownTimer.prototype.onTick = function(ftn) {
if (typeof ftn === 'function') {
this.tickFtns.push(ftn);
}
return this;
};
CountDownTimer.prototype.expired = function() {
return !this.running;
};
CountDownTimer.parse = function(seconds) {
return {
'minutes': (seconds / 60) | 0,
'seconds': (seconds % 60) | 0
};
};
So why is this implementation better than the others? Here are some examples of what you can do with it. Note that all but the first example can't be achieved by the startTimer
functions.
An example that displays the time in XX:XX format and restarts after reaching 00:00
An example that displays the time in two different formats
An example that has two different timers and only one restarts
An example that starts the count down timer when a button is pressed