Javascript - Interval not clearing - javascript

I'm making a game that has a timer in it.
What I'm trying to do is -- when the game starts via gameState.init(), the timer starts through timer.counter("start") -- but when the "restart" button is clicked, the timer stops and resets through timer.counter("reset").
The timer does reset back to 0, but it keeps counting and not getting cleared.
Appreciate any insight I can get. Thanks in advance!
var gameState = {
init: function(){
var difficultyLevel = document.querySelector('input[name="level"]:checked').value;
conditions.difficulty(difficultyLevel);
startFrame.classList.remove("active");
shuffleCards();
timer.counter("start");
display.moves(movesAllowed);
},
restart: function(){
startFrame.classList.add("active");
reset.allCards(cards);
shuffleCards();
timer.counter("reset");
matchCount = 0;
totalMoves = 0;
movesAllowed = 0;
timeAllowed = 0;
time = 0;
}
}
var timer = {
counter: function(status){
var clock = document.querySelector(".timer");
var incrementTime = setInterval(function(){
time++;
var minutes = Math.floor(time / 60);
var seconds = Math.floor(time % 60);
if(seconds < 10){
clock.innerText = minutes + ":0" + seconds;
} else {
clock.innerText = minutes + ":" + seconds;
}
}, 1000);
var stopTime = function(){
clearInterval(incrementTime);
}
if(status === "start"){
alert("counting");
}
if(status === "reset"){;
alert("reset");
stopTime();
}
}
}

Two issues:
The variable that holds the interval, incrementTime, is local to the counter function. Once the counter function ends, incrementTime gets garbage collected, because no reference to the interval remains anymore. You need the interval variable to be persistent instead.
You're setting a new interval every time counter is called. You should probably only set an interval when status is start, otherwise the old interval will continue running and won't be stoppable (reassigning the interval a setInterval is assigned to doesn't clear the interval):
let interval; // <---- Persistent
var timer = {
counter: function(status){
var clock = document.querySelector(".timer");
if (status === 'start') {
interval = setInterval(() => { // <---- Assign to persistent variable
time++;
var minutes = Math.floor(time / 60);
var seconds = Math.floor(time % 60);
if(seconds < 10){
clock.innerText = minutes + ":0" + seconds;
} else {
clock.innerText = minutes + ":" + seconds;
}
}, 1000);
alert("counting");
} else if(status === "reset"){
var stopTime = function(){
clearInterval(interval); // <---- Clear persistent variable
}
alert("reset");
stopTime();
}
}
}
(It would also be a bit more elegant for the stopTime and interval functions to be persistent, rather than being re-created every time they're needed; eg, you might assign them to properties of timer)

Related

How do I stop and reset a setInterval timer

How do I stop and reset this setInterval timer back to 00:00?
Setting clearInterval(timer); works for stopping the time but I can't figure out how to reset the time value back to 00:00.
Here's where I'm at:
HTML
<span class="timer">
<label id="minutes">00</label>:<label id="seconds">00</label>
</span>
JS
const minutesLabel = document.getElementById("minutes");
const secondsLabel = document.getElementById("seconds");
let timer = setInterval(setTime, 1000);
function setTime() {
++totalSeconds;
secondsLabel.innerHTML = pad(totalSeconds % 60);
minutesLabel.innerHTML = pad(parseInt(totalSeconds / 60));
}
function pad(val) {
let valString = val + "";
if (valString.length < 2) {
return "0" + valString;
} else {
return valString;
}
}
stopTimer = () => {
clearInterval(timer);
timer = setInterval(setTime, 1000);
};
I'm using this timer in a game so based on the users state I need to be able start, stop, and restart the time back to 0.
What's happening now is that your variable keeps going up, even when you "reset" the timer.
Simply add
totalSeconds = 0;
to your stopTimer function. This will reset the variable to zero.
The variable totalSeconds keeps track of your time.
The name of your function stopTimer() - maybe it should be restartTimer - seems a bit misleading since you're restarting the timer there but basically just set totalSeconds to 0 like:
stopTimer = () => {
totalSeconds = 0;
clearInterval(timer);
timer = setInterval(setTime, 1000);
};

Countdown Timer not Stopping with clearInterval()

I'm having a problem get this countdown timer to stop at zero so the time won't show as a negative value. The console.log is getting called and works fine but for some reason the clearInterval() is not. This is driving me crazy and I'm close to quitting.
const timerContainer = document.getElementById('timerContainer');
const THREEMINUTES = 60 * 0.1;//5 seconds for testing
startTimer(THREEMINUTES, timerContainer);
function startTimer(duration, display) {
let start = Date.now();
let diff, min, sec;
let timer = () => {
diff = duration - (((Date.now() - start) / 1000) | 0);
//use bitwise to truncate the float
min = (diff / 60) | 0;
sec = (diff % 60) | 0;
min = min < 10 ? '0' + min : min;
sec = sec < 10 ? '0' + sec : sec;
display.textContent = min + ':' + sec;
if (diff <= 0) {
stopTimer();
submit.disabled = 'true';
};
};
//call timer immediately otherwise we wait a full second
timer();
setInterval(timer, 1000);
function stopTimer() {
clearInterval(timer);
console.log("time's up", diff);
};
}
<div id="timerContainer"></div>
You are not saving the result of setInterval(timer, 1000);
you should use this:
let timerId;
timer();
timerId = setInterval(timer, 1000);
function stopTimer() {
clearInterval(timerId);
console.log("time's up", diff)
};
As you might see, the result of setInterval is a number (object in node), and all you then need to do is pass that value to clearInterval thus we save the value in the variable timerId for reference.
Don't pass the function that you want stopped to clearInterval().
Pass a reference to the timer that you started, so you need to make sure that when you start a timer, you capture a reference to the ID that will be returned from it.
// Function that the timer will invoke
function callback(){
. . .
}
// Set up and initiate a timer and capture a reference to its unique ID
var timerID = setInterval(callback, 1000);
// When needed, cancel the timer by passing the reference to it
clearInterval(timerID);
The code is fixed make sure you fix your submit button code.
You should first assign the value of setInterval to a variable. That variable is used while calling clearInterval which infact clears the interval.
const timerContainer = document.getElementById('timerContainer');
const THREEMINUTES = 60 * 0.1;//5 seconds for testing
startTimer(THREEMINUTES, timerContainer);
var timer = null;
function startTimer(duration, display) {
let start = Date.now();
let diff, min, sec;
let timer = () => {
diff = duration - (((Date.now() - start) / 1000) | 0);
//use bitwise to truncate the float
min = (diff / 60) | 0;
sec = (diff % 60) | 0;
min = min < 10 ? '0' + min : min;
sec = sec < 10 ? '0' + sec : sec;
display.textContent = min + ':' + sec;
if (diff <= 0) {
stopTimer();
submit.disabled = 'true';
};
};
//call timer immediately otherwise we wait a full second
timer();
timer = setInterval(timer, 1000);
function stopTimer() {
clearInterval(timer);
console.log("time's up", diff);
};
}

wants javascript countdown to continue from where it was even after refresh

I am designing a javaScript countdown for 3 hours using the below code
<div id="timer"></div>
<script type="text/javascript">
var count = 10800;
var counter = setInterval(timer, 1000); //1000 will run it every 1 second
function timer() {
count = count - 1;
if (count == -1) {
clearInterval(counter);
return;
}
var seconds = count % 60;
var minutes = Math.floor(count / 60);
var hours = Math.floor(minutes / 60);
minutes %= 60;
hours %= 60;
document.getElementById("timer").innerHTML = hours + "hours " + minutes + "minutes and " + seconds + " seconds left to complete this transaction"; // watch for spelling
}
</script>
but the only issue I am having here is whenever I refresh the page the countdown starts all over again. I want it to resume from where it stopped.
You need to store the data into some persistent storage method, such as cookies, the browsers localStorage, or write data out to an external data source (such as a database through an API). Otherwise the session data is lost between browser refreshes.
For example, if you wanted to use localStorage:
<script type="text/javascript">
// properties
var count = 0;
var counter = null;
window.onload = function() {
initCounter();
};
function initCounter() {
// get count from localStorage, or set to initial value of 1000
count = getLocalStorage('count') || 1000;
counter = setInterval(timer, 1000); //1000 will run it every 1 second
}
function setLocalStorage(key, val) {
if (window.localStorage) {
window.localStorage.setItem(key, val);
}
return val;
}
function getLocalStorage(key) {
return window.localStorage ? window.localStorage.getItem(key) : '';
}
function timer() {
count = setLocalStorage('count', count - 1);
if (count == -1) {
clearInterval(counter);
return;
}
var seconds = count % 60;
var minutes = Math.floor(count / 60);
var hours = Math.floor(minutes / 60);
minutes %= 60;
hours %= 60;
document.getElementById("timer").innerHTML = hours + "hours " + minutes + "minutes and " + seconds + " seconds left to complete this transaction"; // watch for spelling
}
</script>
<div id="timer"></div>
You can try it out here: https://jsfiddle.net/rcg4mt9x/

create a stop watch falls with error

I have a stop watch which works good but in sec value after 60 sec i need the timer to go to zero and min to 1, And in the same way for every 60 sec min should change
/* Stopwatch */
starttime(){
console.log("timer started");
if( this.running == 0){
this.running = 1;
this.adder()
}else{
this.running = 0;
}
}
reset(){
console.log("timer reset");
this.running = 0;
this.time = 0;
this.total = 0;
this.Sec = 0;
}
adder(){
console.log("timer incrementor");
if(this.running == 1){
setTimeout(()=>{
this.time++;
var mins = Math.floor(this.time/10/60);
var sec = Math.floor(this.time / 10 );
var tens = this.time/10;
this.total = mins + ':' + sec;
console.log(this.total) ;
this.Sec = sec;
this.adder()
},10)
}
}
But here time changes, sec gets added up it does not goes to zero when it reaches 60 it moves on to 61,62,63.... sample time after 120 secs is 0:2:120, What i need is 0:2:0 (hrs:sec:min)
worked fine after modifying ' var sec = Math.floor(this.time / 10)%60;' and changed set time out time to
this.adder()
},100)
In case you have the option, use moment.js to format the elapsed time.
this.total = moment.utc(this.time).format("mm:ss.SSS"))
Otherwise ignore this answer ;)
I think your calculation for second is wrong. use following statement instead of yours.
var sec = Math.floor(this.time / 10)%60;

JavaScript timer doesn't start after being reset

The timer, start/pause button and reset button all work as expected.
The only bug it seems to have is, when I run the timer and reset it, it
won't start again. Only after I press the Start/Pause button 2 times it will run again.
Live demo: http://codepen.io/Michel85/full/pjjpYY/
Code:
var timerTime;
var time = 1500;
var currentTime;
var flag = 0;
var calculateTime
// Start your Timer
function startTimer(time) {
document.getElementById("btnUp").disabled = true;
document.getElementById("btnDwn").disabled = true;
timerTime = setInterval(function(){
showTimer();
return flag = 1;
}, 1000);
}
// Reset function
function resetTimer(){
clearInterval(timerTime);
document.getElementById('showTime').innerHTML=(calculateTime(1500));
document.getElementById("btnUp").disabled = false;
document.getElementById("btnDwn").disabled = false;
return time=1500;
}
// Pause function
function pauseTimer(){
clearInterval(timerTime);
currentTime = time;
document.getElementById('showTime').innerHTML=(calculateTime(time));
return flag = 0;
}
// Update field with timer information
function showTimer(){
document.getElementById("showTime").innerHTML=(calculateTime(time));
flag = 1;
if(time < 1){
resetTimer();
}
time--;
};
// Toggle function (Pause/Run)
function toggleTimmer(){
if(flag == 1){
pauseTimer();
} else {
startTimer();
}
}
/*
Round-time up or down
*/
// Set timer Up
function timeUp(){
time += 60;
document.getElementById("showTime").innerHTML=(calculateTime(time));
return time;
}
// Set timer Down
function timeDown(){
if(time > 60){
time-=60;
}
document.getElementById("showTime").innerHTML=(calculateTime(time));
return time;
}
/*
Break-time up down
*/
// Set timer Up
function breakUp(){
time += 60;
document.getElementById("showTime").innerHTML=(calculateTime(time));
return time;
}
// Set timer Down
function breakDown(){
if(time > 60){
time-=60;
}
document.getElementById("showTime").innerHTML=(calculateTime(time));
return time;
}
// Calculate the Days, Hours, Minutes, seconds and present them in a digital way.
function calculateTime(totalTime) {
// calculate days
var days = Math.floor(totalTime / 86400);
totalTime = totalTime % 86400
// calculate hours
var hours = Math.floor(totalTime / 3600);
totalTime = totalTime % 3600;
// calculate minutes
var minutes = Math.floor(totalTime / 60);
totalTime = totalTime % 60;
// calculate seconds
var seconds = Math.floor(totalTime);
function convertTime(t) {
return ( t < 10 ? "0" : "" ) + t;
}
// assign the variables
days = convertTime(days);
hours = convertTime(hours);
minutes = convertTime(minutes);
seconds = convertTime(seconds);
// Make sure the "00:" is present if empty.
if(days !== "00"){
var currentTimeString = days + ":" + hours + ":" + minutes + ":" + seconds;
return currentTimeString;
} else if (hours !== "00"){
var currentTimeString = hours + ":" + minutes + ":" + seconds;
return currentTimeString
} else if(minutes !== "0:00"){
var currentTimeString = minutes + ":" + seconds;
return currentTimeString
} else {
var currentTimeString = seconds;
return currentTimeString
}
}
Any help is welcome.
Thanks in advance.
Greets,
Michel
resetTimer needs to set flag to 0. If it leaves it set at 1, then toggleTimer will call pauseTimer rather than startTimer.
BTW, it's better style to use boolean values (true/false) for flags.
Just remove clearInterval(timerTime); in function resetTimer();
function resetTimer() {
//clearInterval(timerTime);
document.getElementById('showTime').innerHTML = (calculateTime(300));
document.getElementById("btnUp").disabled = false;
document.getElementById("btnDwn").disabled = false;
return time = 300;
}

Categories

Resources