NZMAI
NZMAI

Reputation: 546

Timer does not actually stop after pause button is clicked

Timer is displayed as if it is kind of stop after pause button is clicked, but when i click resume i find out that counter continue to countdown behind the scene. I guess there are issues with setInterval. Please help me. My project on CodePen for reference if you need.

My timer function

function timer(seconds) {
  clearInterval(countdown);
  const now = Date.now();
  const then = now + seconds * 1000;
  displayTimerLeft(seconds);
  console.log({
    now,
    then
  });
  countdown = setInterval(() => {
    if (!isPaused) {
      const remainSeconds = Math.round((then - Date.now()) / 1000);
      if (remainSeconds < 0) {
        clearInterval(countdown);
        return;
      }
      displayTimerLeft(remainSeconds);

    }
  }, 1000);

}

Pause and start click events

pause.addEventListener('click', function() {
  isPaused = true;
  return;

})

start.addEventListener('click', function() {
  isPaused = false;
})

Upvotes: 1

Views: 324

Answers (3)

Miguel
Miguel

Reputation: 20633

Keep a reference of the current time and manually add a second at each tick.

function timer(seconds) {
  clearInterval(countdown);
  const t = new Date();
  const end = t.getTime() + seconds * 1000;
  displayTimerLeft(seconds);
  console.log({
    t,
    end
  });
  countdown = setInterval(() => {
    if (!isPaused) {
      const remainSeconds = Math.round((end - t.getTime()) / 1000);
      if (remainSeconds < 0) {
        clearInterval(countdown);
        return;
      }
      displayTimerLeft(remainSeconds);
      t.setSeconds(t.getSeconds() + 1);
    }
  }, 1000);
}

Demo: http://codepen.io/miguelmota/pen/wgMzXY

Upvotes: 2

Marc-Antoine Parent
Marc-Antoine Parent

Reputation: 340

Looking at your code, I suppose the problem is you keep the same then value, which is ultimately a timestamp at which the timer should end. Right now, instead of pausing the countdown, you stop the display from changing.

I would advise using your variable seconds instead (and calculating display using modulo %), and decreasing it every second. That way, pausing the display would effectively pause the decreasing.

Upvotes: 4

Akram Saouri
Akram Saouri

Reputation: 1169

setInterval returns a unique id that can be used to stop the timer using clearInterval:

var id = setInterval(function(){
console.log('running every 300 ms');
},300);

clearInterval(id) // stop timer

Upvotes: -2

Related Questions