How to write a countdown timer in JavaScript?
Solution 1
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) {
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.textContent = minutes + ":" + seconds;
if (--timer < 0) {
timer = duration;
}
}, 1000);
}
window.onload = function () {
var fiveMinutes = 60 * 5,
display = document.querySelector('#time');
startTimer(fiveMinutes, display);
};
<body>
<div>Registration closes in <span id="time">05:00</span> minutes!</div>
</body>
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) {
var start = Date.now(),
diff,
minutes,
seconds;
function timer() {
// get the number of seconds that have elapsed since
// startTimer() was called
diff = duration - (((Date.now() - start) / 1000) | 0);
// does the same job as parseInt truncates the float
minutes = (diff / 60) | 0;
seconds = (diff % 60) | 0;
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = minutes + ":" + seconds;
if (diff <= 0) {
// add one second so that the count down starts at the full duration
// example 05:00 not 04:59
start = Date.now() + 1000;
}
};
// we don't want to wait a full second before the timer starts
timer();
setInterval(timer, 1000);
}
window.onload = function () {
var fiveMinutes = 60 * 5,
display = document.querySelector('#time');
startTimer(fiveMinutes, display);
};
<body>
<div>Registration closes in <span id="time"></span> minutes!</div>
</body>
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?"
- Should a count down timer count down? Yes
- Should a count down timer know how to display itself on the DOM? No
- Should a count down timer know to restart itself when it reaches 0? No
- Should a count down timer provide a way for a client to access how much time is left? Yes
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
Solution 2
You can easily create a timer functionality by using setInterval.Below is the code which you can use it to create the timer.
http://jsfiddle.net/ayyadurai/GXzhZ/1/
window.onload = function() {
var minute = 5;
var sec = 60;
setInterval(function() {
document.getElementById("timer").innerHTML = minute + " : " + sec;
sec--;
if (sec == 00) {
minute --;
sec = 60;
if (minute == 0) {
minute = 5;
}
}
}, 1000);
}
Registration closes in <span id="timer">05:00<span> minutes!
Solution 3
If you want a real timer you need to use the date object.
Calculate the difference.
Format your string.
window.onload=function(){
var start=Date.now(),r=document.getElementById('r');
(function f(){
var diff=Date.now()-start,ns=(((3e5-diff)/1e3)>>0),m=(ns/60)>>0,s=ns-m*60;
r.textContent="Registration closes in "+m+':'+((''+s).length>1?'':'0')+s;
if(diff>3e5){
start=Date.now()
}
setTimeout(f,1e3);
})();
}
Example
Jsfiddle
not so precise timer
var time=5*60,r=document.getElementById('r'),tmp=time;
setInterval(function(){
var c=tmp--,m=(c/60)>>0,s=(c-m*60)+'';
r.textContent='Registration closes in '+m+':'+(s.length>1?'':'0')+s
tmp!=0||(tmp=time);
},1000);
JsFiddle
Related videos on Youtube
Bartek
Updated on March 12, 2021Comments
-
Bartek about 3 years
Just wanted to ask how to create the simplest possible countdown timer.
There'll be a sentence on the site saying:
"Registration closes in 05:00 minutes!"
So, what I want to do is to create a simple js countdown timer that goes from "05:00" to "00:00" and then resets to "05:00" once it ends.
I was going through some answers before, but they all seem too intense (Date objects, etc.) for what I want to do.
-
Sikshya Maharjan over 10 yearsAnd again, you're leaving out the relevant HTML, though at least you've sort of explained the complexity issue this time. But seriously, you need to look into making a solution yourself, and then come and ask us about problems you're having.
-
bjb568 over 10 yearsCode examples with complaints on how they are too complicated? Anyway, I think you could easily
setInterval
and make it .innerHTML based, instead of date based. -
Carlos Rafael Ramirez about 9 yearsYes, people should look for making the solution themselves. But with javaScript there are plenty examples of doing common tasks. I know how to do a count down timer, but I prefer if I find one in the web (like a component). So thanks to this question and the extensive answer I found what I was looking for. Countdown logic
-
nu everest over 7 yearsI found these solutions to be simpler: stackoverflow.com/questions/32141035/…
-
Erich García over 7 years
-
-
Bartek over 10 yearsYou're the man! That's exactly what I was looking for. Thank you! One more thing: how can I add "0" in front of minutes, so it shows "04:59", instead of "4:59"?
-
robbmj over 10 years
minutes = minutes < 10 ? "0" + minutes : minutes;
-
timbram almost 9 yearsIn the very first demo, with Vanilla JavaScript, what kind of variable is timer? I have never seen anything like that! And how can you set it when minutes and seconds are not yet defined?
-
robbmj almost 9 years@timbram
timer
, initially is just a copy of the paramaterduration
and it is just a number. The reason why it is needed is to keep track of the remaining time, that can't be done with theduration
parameter as the timer needs to be reset when it reaches 0.minutes
andseconds
are calculated based on the value oftimer
. Hope this helps. -
abustamam almost 9 years@timbram it looked weird to me at first too, until i realized that a comma after a
var
declaration separates different declarations. sominutes
andseconds
are simply declared (but un-initialized) variables. sotimer
is simply just equal the theduration
parameter, nothing more, nothing less. -
Sinan Erdem about 8 yearsThank you! What is the best way to add Pause/Resume functionality to the last script?
-
robbmj about 8 years@SinanErdem I have written some code that does this. I can add that code to the answer later today. I will ping you when this is done.
-
Savvas Parastatidis about 8 yearsIs there a way to find the current value of the timer or how much time has passed since its start? I could parse the html value but it's a bit silly when the real value is there!
-
Sangamesh Davey almost 8 yearsHow to call a functions once the timer become 00:00???
-
Santosh Pillai almost 8 yearsis there any way to stop the js demo from resetting once it reaches 0 ?
-
Santosh Pillai almost 8 yearsstopped it from resetting by if (--timer < 0) { timer = 0; }
-
Dzung Nguyen over 7 yearsHow do you add a reset options? And also a pause and resume? I tried adding a field this.reset, and check that in the closure. But the clock keeps going though.
-
Edgar over 7 years
(diff / 60) | 0;
- what is|
here? How is it called? -
Edgar over 7 yearsI found this answer: stackoverflow.com/questions/7487977/… . What I was looking for.
-
robbmj over 7 years@Edgar yep that's what it does.
-
Ricky Mason about 7 years@robbmj Hey - great post. Thanks - Did you ever implement the pause feature? Could really use that in one of the projects im working on.
-
BornToCode over 6 yearsIn what way is the second version "more accurate"?
-
robbmj over 6 years@BornToCode Using a Date object to calculate exactly how much time is remaining or has elapsed is needed as
setInterval
andsetTimeout
can't guarantee that they will be called in exactlyn
milliseconds. -
Scott Rowley over 6 yearsDoes not accurately represent each second, it's counting down much too fast.
-
Scott Rowley over 6 yearsChanging the 500 to 1000 seems to make it accurate.
-
shikiko over 6 yearsanyone know hwo to add ike 2 more minutes after it stops at 0?
-
Mike Pala over 6 years@robbmj I really like your solution... the first one, the vanilla one :) if you have a moment could you please show me how you would add a reset button to that solution. I mean a button that would NOT stop the timer... just reset it back to 5:00 ... so it would automatically go to 4:59... 4:58 ... etc
-
epascarello about 6 yearsAnswer is flawed because of the use of setTimeout/Interval since it does not fire accurately.
-
robbmj about 6 years@epascarello please see last section for a more accurate timer that deals with the inaccuracy of
setTimeout
andsetInterval
. -
Zoltán Süle over 5 yearsthere is a bug in the jquery code: displayId.text(minutes + ":" + seconds); The right way is: displayId.html(minutes + ":" + seconds);
-
robbmj over 5 years@ZoltánSüle I should probably update the answer so that the normal JS uses innerHTML as well.
-
Zoltán Süle over 5 years@robbmj I was wrong. In this case there is no real difference between the text() and the html() functions
-
robbmj over 5 years@ZoltánSüle no worries, better to point something out and be wrong then let a potential bug slip through.
-
Mostafa over 5 yearsHow stop timer after a button clicked...and then start it again after another click?
-
Melu about 5 yearsexcellent timer, one suggestion is to do something like var objMyInterval = setInterval(function timer() {... now to stop timer after minutes <= 0 & seconds <=0 just call clearInterval(objMyInterval);
-
V1xIII almost 4 yearsHow would you go about making the simple example also display hours?
-
robbmj almost 4 years@V1xIII This should do what you want: jsfiddle.net/ejdcwmuy
-
embulldogs99 almost 4 yearsSlick solution, hour should be changed to minute though to avoid confusion
-
Shiz over 3 yearsthough it doesn't look
simplest
to me -
LeCoda almost 3 yearsIf I want to include Hours, so have as output to display a common Hrs:Mins:Sec output, how would I change this code
-
Pedro Joaquín almost 3 yearsis there any way to restart the timer? i tried but it just launches several timers at the same time