How to resume a timer?

1.4k views Asked by At

I'm trying to implement a timer which does a countdown from 60 seconds. I am able to pause the timer when I click the pause button, but when I click it again to resume, it resets the timer back to 60 seconds.

Here's a snippet of the code:

var t = 0;

function pause_game(pause_button){
    var elem = document.getElementById('pause_button');
    var lastTime;
    if (elem.value=="PAUSE"){
        lastTime = clearTimeout(t);
        elem.value = "RESUME";
    }
    if (elem.value=="RESUME"){
        countdownTimer(lastTime);
        elem.value = "PAUSE";
    }
}

function countdownTimer(secs) {
    var game_page = document.getElementById('game_page');
    var start_page = document.getElementById('start_page');
    var seconds = 60;
    function tick() {
        var counter = document.getElementById("timer");
        seconds--;
        counter.innerHTML = "0" + ":" + (seconds < 10 ? "0" : "") + String(seconds);
        if(seconds > 0) {
            t = setTimeout(tick, 1000);
        }
        else {
            setTimeout(function () {
            game_page.style.display = 'none';
            start_page.style.display = 'block';
            }, 1000)
        }
    tick();
}

Can't seem to figure out what went wrong. Help would be greatly appreciated. Thanks!

2

There are 2 answers

0
Surely On

The t variable won't return current countdown value, it returns the setTimeout id, which used to cancel the timeout function.

So you have to use another variable to record down the current countdown seconds and in the countDownTimer function, instead of assign 60 to seconds, assign the recorded current countdown seconds.

Or you can use a setInterval function to do the countdown job and set a pause boolean value to denote the status:

var paused = false;
var t;
function countDownTimer(seconds){
    //before create another timer, remember to cancel the previous one, if has
    clearInterval(t);
    t = setInterval(function(){
        if(!paused){
          seconds--;
          console.log(seconds);
          //you can do display or whatever things here.
        }
    }, 1000)
}
function pauseOrResumeTimer(){
    paused = !paused;
}
0
AlienWebguy On

You can't resume a timer - what you can do is capture the difference between how much time has passed and how much is remaining when you "pause" the timer, and then when you want to "unpause" you set a new timer for that remainder.

Consider this snippet from a backbone project I did ages ago:

/**
 * Method 'pauses' the timer by clearing the timer from the global
 * object timeout queue and logging the remaining time. When we 'unpause',
 * we simply create a new timer with the remaining time.
 * @return MEP.Timer
 */
pause : function () {
    // Don't try to pause if it is already paused.
    if (this.get('state') === 'live') {
        window.clearTimeout(this.get('timerId'));
        this.setRemainingTime(this.get('remaining') - (new Date() - this.get('start')));
        this.setState('paused');
    }
    return this;
},

/**
 * Method sets a timer with the remaining time from the previously paused
 * timer. New timers also call this method by adding the full timer delay
 * as the remaining delay to consolidate functionality.
 * @return MEP.Timer
 */
resume : function () {
    if (this.get('state') === 'paused') {
        this.createTimer(this.get('callback'), this.get('remaining'), null);
    }
    return this;
},