简体   繁体   中英

Countdown Timer only stops when the page is refreshed

I borrowed a countdown timer code from stackoverflow and it was working fine until I decided to add another code from stackoverflow that uses localStorage so the timer will continue even after the page refreshes. My timer should stop when the totalSeconds is 0 but because there is a localStorage, it doesn't know what the totalSeconds' value should be. Is my if statement for totalSeconds correct? It only works when the page refreshes but doesn't recognize the timer as it counts down.

  quiztime: res.data[x].Time; //This was a variable from my get function that based on user input
              
           var totalSeconds = 0;

            if (this.quizTime != 0) {

            if(localStorage.getItem("totalSeconds")){
                  totalSeconds = localStorage.getItem("totalSeconds");  
              } else {
                  totalSeconds = this.quizTime;
              }
            }
             
            if(totalSeconds <= 0){ 
                    setTimeout(this.submitMyAnswer(), 3000);
                  } else {
                    setTimeout(setTime, 1000);
                  }
           
              var minutesLabel = document.getElementById("minutes");
              var secondsLabel = document.getElementById("seconds");
              setInterval(setTime, 1000);
                

                function setTime() {
                --totalSeconds;
                secondsLabel.innerHTML = pad(totalSeconds % 60);
                minutesLabel.innerHTML = pad(parseInt(totalSeconds / 60));
                localStorage.setItem("totalSeconds", totalSeconds);
                }
 
              function pad(val) {
                var valString = val + "";
                if (valString.length < 2) {
                  return "0" + valString;
                } else {
                  return valString;
                }
              }

              window.addEventListener("beforeunload", function (e) {
                e.preventDefault();
                s;
                e.returnValue = "";
              });
        
            
        });
    },

You need to store the return value of setTimeout in a variable. Then, you just clear the interval with clearTimeout method.

eg:

const milisecs = 1000 // one sec

const timeout = setTimeout(() => {
 // do some stuff here
}, milisecs)

// after doing other stuff... farewell dear timeout, we won't forget you
clearTimeout(timeout)

Same thing goes for setInterval and clearInterval

There are few mistakes in your code.

Do not use parenthesis () with setTmeout callback ( setTimeout(this.submitMyAnswer(), 3000); ). As it will invoke return value from submitMyAnswer() after timeout . I guess you are supposed to call submitMyAnswer after 3 seconds so just use

setTimeout(this.submitMyAnswer, 3000);


Another thing is you want to clear interval after totalSeconds is become 0. To stop interval you should be using clearInterval also refer How to use setInterval and clearInterval? .

In your case you have to assign return value from setInterval to any object, say interval , and when add condition in setTime when totalSeconds <= 0 then clearInterval(interval). Your updated code would be like below.

Refer setInterval , you can pass parameter to with setInterval .

Comment out below code as it won't be needed. Call submitMyAnswer from setTime inside if condition as per below code.

// Comment below code. It will not needed.
//if (totalSeconds <= 0) {
//  setTimeout(this.submitMyAnswer, 3000);
//} else {
//  setTimeout(setTime, 1000);
//}

// assign return value from setInterval to object
// pass this.submitMyAnswer function as parameter so it can be invoked when totalSeconds become 0, Note : Do not use () as this.submitMyAnswer()
var interval = setInterval(setTime, 1000, this.submitMyAnswer);

// get callback function submitMyAnswer in parameter to invoke when time elapsed.
function setTime(submitMyAnswer) {
  --totalSeconds;
  secondsLabel.innerHTML = pad(totalSeconds % 60);
  minutesLabel.innerHTML = pad(parseInt(totalSeconds / 60));
  localStorage.setItem("totalSeconds", totalSeconds);

  // clear interval once totalSeconds is 0
  if (totalSeconds <= 0) {
    clearInterval(interval);

    // call submitMyAnswer() once totalSeconds become 0.
    // do not use this.submitMyAnswer(), simply use submitMyAnswer()
    submitMyAnswer();
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM