322

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.

5
  • 5
    And 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. Commented Dec 16, 2013 at 18:43
  • Code 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. Commented Dec 16, 2013 at 18:44
  • 2
    Yes, 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 Commented Apr 7, 2015 at 2:48
  • 2
    I found these solutions to be simpler: stackoverflow.com/questions/32141035/… Commented Aug 25, 2016 at 21:11
  • Look this: sitepoint.com/build-javascript-countdown-timer-no-dependencies Commented Jan 16, 2017 at 20:01

3 Answers 3

687

I have two demos, one with jQuery and one without. Neither use date functions and are about as simple as it gets.

Demo with vanilla JavaScript (version with a start/stop button here)

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>

Demo with jQuery (version with a start/stop button here)

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: (version with a start/stop button here)

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

Sign up to request clarification or add additional context in comments.

32 Comments

You'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"?
minutes = minutes < 10 ? "0" + minutes : minutes;
@timbram it looked weird to me at first too, until i realized that a comma after a var declaration separates different declarations. so minutes and seconds are simply declared (but un-initialized) variables. so timer is simply just equal the the duration parameter, nothing more, nothing less.
stopped it from resetting by if (--timer < 0) { timer = 0; }
How 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.
|
42

You can easily create a timer functionality by using setInterval() function. 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">5:00</span>!

6 Comments

Does not accurately represent each second, it's counting down much too fast.
Changing the 500 to 1000 seems to make it accurate.
Slick solution, hour should be changed to minute though to avoid confusion
Seems like 5:60 should never be a thing.
Multiple issues: 1) this is supposed to be a 5 minute timer, not a 5 minute and 60 second timer. 2) Why is sec being set to 60? 5:60 isn't valid for timers. This would mean 6 minutes but treated as 5 minutes by this code. 3) The timer never shows 5:00 but instead shows 4:60, etc. 4) When the timer gets to 0 minutes and 60 seconds, the timer starts over again when there's still a minute left according to the display. 5) When the timer's seconds goes into single digits, it's not using a leading zero. 6) Also have to wait a full second before the 1 second interval kicks in.
|
33

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.