Error with count up when use setInterval and clearInterval - javascript

I use countTime function for incrementing timer, I have 1 function gameStart to initialize game structures and assign variable totalSecond = 0 and variable timeStart = setInterval(countTime, 1000). I have a button that when clicked it will run the function gameStart. When I run the code for the first time, everything is fine, but when I press the button many times with the newGame event, it increases the time very quickly. I have to clearInteval when I lose the game so time can stop. Thank for help me
function countTimer() {
totalSeconds++;
var hour = Math.floor(totalSeconds /3600);
var minute = Math.floor((totalSeconds - hour*3600)/60);
var seconds = totalSeconds - (hour*3600 + minute*60);
if(hour < 10)
hour = "0"+hour;
if(minute < 10)
minute = "0"+minute;
if(seconds < 10)
seconds = "0"+seconds;
document.getElementById("countUp").innerHTML = hour + ":" + minute + ":" + seconds;
}
function gameStart() {
timerVar = setInterval(countTimer, 1000);
totalSeconds = 0;
rows = parseInt(document.getElementById("rows").value);
cols = parseInt(document.getElementById("cols").value);
mineCount = parseInt(document.getElementById("mines").value);
rows = rows > 10 ? rows : 10;
cols = cols > 10 ? cols : 10;
mCount = mCount > 10 ? mCount : 10;
openedCells=0;
initBoard();
initHTML();
}

setInterval functions never expire until you call clearInterval. In your case, every time you run gameStart, a new interval is created that counts up.
You are left with multiple intervals, making the timer go up quicker and quicker.
A quick fix would be to declare timerVar outside the Function, then clear and re-make it every time gameStart is called.
timerVar = setInterval(()=>{},1000) // Empty interval
function gameStart() {
clearInterval(timerVar)
timerVar = setInterval(countTimer, 1000);
totalSeconds = 0;
I'm unable to test this at the moment, but it should work.

Related

Updating the button element as a countdown timer through javascript

I want to create a countdown timer which looks like an fps counter for webpage...
after hours of time spent i m not able to find out what is wrong.....help
<script>
var myvar = setInterval(function () { startTimer() }, 1000);
function startTimer() {
var presentTime = 17 + ":" + 00;
var timeArray = presentTime.split(/[:]+/);
var m = timeArray[0];
var s = checkSecond((timeArray[1] - 1));
if (s == 59) {
m = m - 1
}
//if(m<0){alert('timer completed')}
var button2 = document.createElement("Button2");
var interval = m + s;
button2.innerHTML = Math.round(interval);
button2.style = "top:0; left:0rem; height:10% ;color: black; background-color: #ffffff;position:fixed;padding:20px;font-size:large;font-weight: bold;";
setTimeout(startTimer, 1000);
document.body.appendChild(button2);
}
function checkSecond(sec) {
if (sec < 10 && sec >= 0) {
sec = "0" + sec
}; // add zero in front of numbers < 10
if (sec < 0) {
sec = "59"
};
return sec;
}
</script>
I can find three errors that hinder your code from performing correctly.
Multiple timers
First off since you invoke both a setInterval in outer scope, and then a setTimeout after each performed iteration, you will end up getting many unwanted timer instances that will do some crazy counting for you.
I recommend you to scrap either one of these and stick with just one of them.
For my example i happend to stick with the setInterval since you're executing the very same method over and over any way.
The initialization
Since the presentTime is declared inside the startTimer-function it will be constantly overwritten with 17 + ":" + 00 (resulting in "17:0" btw).
This is solved by declaring it in the outer scope instead.
Remembering the changes
Finally you need to save the current state of presentTime after modifications. Just adding a presentTime = [m,s].join(":"); at the end of startTimer() solves this.
var presentTime = "17:00";
function startTimer() {
var timeArray = presentTime.split(/[:]+/);
var m = timeArray[0];
var s = checkSecond((timeArray[1] - 1));
if (s == 59) {
m = m - 1
}
var button2 = document.createElement("Button2");
var interval = s;
button2.innerHTML = m + ":" + s;
button2.style = "top:0; left:0rem; height:10% ;color: black; background-color: #ffffff;position:fixed;padding:20px;font-size:large;font-weight: bold;";
document.body.appendChild(button2);
presentTime = [m,s].join(":");
}
function checkSecond(sec) {
if (sec < 10 && sec >= 0) {
sec = "0" + sec
}; // add zero in front of numbers < 10
if (sec < 0) {
sec = "59"
};
return sec;
}
var interval = setInterval(startTimer, 1000);

clearInterval is not clearing setInterval

I have made a memory game with a timer that start at 10 minutes and counts down every second to 0. This function is only called once and has the following setInterval function:
game.countdown = setInterval(function() {
if(game.timeLeft <= 0){
gameEnded = true;
}
if(!gameEnded){
// lower one second
game.timeLeft--;
var timespan = document.querySelector('.timeleft');
var minutes = pad(Math.floor((game.timeLeft / 60)),2 );
var newSeconds = pad(Math.floor(game.timeLeft - (minutes * 60)),2 );
function pad(num, size) {
var s = num+"";
while (s.length < size) s = "0" + s;
return s;
}
var niceTime = minutes + ":" + newSeconds;
timespan.innerHTML = niceTime;
// Then alter time bar on .innertimer
// Calculate percentage starting at 0%
var percentageDone = (Math.floor((10*60 - game.timeLeft) / (10*60) * 10000) / 100);
$(".timer").css({"background": "-webkit-linear-gradient(left, white " + percentageDone + "%, green " + percentageDone + "%)"});
}
}, 1000);
I store the setInterval in object game under variable name countdown. When the game is ended I call another function that has the clearInterval:
clearInterval(game.countdown);
Then when it goes to the next level it calls the setInterval function again and stores it again in game.countdown. But now for every second it takes 2 seconds. The next level 3 seconds. You can see there are multiple setInterval's at work because it's not done at the same time.
Hope someone can really help me out debugging this problem.
What I've done to work around the issue is the following. The interval is only being called if the following is true:
if (undefined == game.countdown){
This way if there is a countdown defined it's calling it again. And since I'm storing the game.timeLeft not in the function itself I can just refill game.timeLeft.

Javascript timer slows down when when repetitively updating DOM element inside setInterval()

I am creating an application that uses a timer to draw lines to several canvases while updating stats to DIVs. In order to create the smoothest animation possible I've had to set the setInterval() timer to the smallest delay possible, which from my understanding, is between 10-15 milliseconds across browsers.
The issue I am having is with the stopwatch that tracks the scenarios running time. The stopwatch itself works well enough as I have established using console.log, however, the setInterval() timer slows down when I try to update the DOM element. This has lead me to believe that in combination with the small timer tick delay there is a performance issue with the way I am updating the DOM element.
Code:
function draw() {
var drawTimer = setInterval(drawStuffTest, 15);
var timer = doc.getElementById('time');
var milliseconds = 0;
var seconds = 0;
var minutes = 0;
function updateTimer() {
//clear the old elapsed time
timer.innerHTML = "";
milliseconds += 15;
//increment seconds
if (milliseconds >= 1000) {
seconds++;
milliseconds = 0;
}
//increment minutes
if(seconds >= 60)
{
seconds = 0;
minutes++;
}
//Pad minutes and seconds with leading zeroes if either is lest than 10
var secondsString = ( seconds < 10 ? "0" : "" ) + seconds;
var minutesString = ( minutes < 10 ? "0" : "" ) + minutes;
var elapsedTime = minutesString + ":" + secondsString;
/* The timer works fine when I just use console.log to display the
timer however once I add the following statement to update the DOM
element the timer slows down */
//timer.innerHTML = elapsedTime;
console.log(elapsedTime);
}
Does anyone have any suggestions?

javascript count down timer flickering on calling more than once

function countdown(element, minutes, seconds) {
// set time for the particular countdown
var time = minutes*60 + seconds;
var interval = setInterval(function() {
var el = document.getElementById(element);
// if the time is 0 then end the counter
if(time == 0) {
//el.innerHTML = "countdown's over!";
// document.getElementById("timer").style.visibility="hidden";
clearInterval(interval);
return;
}
var hour=Math.floor( time / (60*60) );
if (hour < 10) hour = "0" + hour;
var minutes = 0;
if(time>=60 && hour>0)
minutes=Math.floor( (time / 60 )-60);
else{
minutes=Math.floor( (time / 60 ));
}
if (minutes < 10) minutes = "0" + minutes;
var seconds = time % 60;
if (seconds < 10) seconds = "0" + seconds;
// var text = hour+":"+minutes; //+ ':' + seconds;
var text = minutes; //+ ':' + seconds;
el.innerHTML = text;
time--;
}, 1000);
}
when i am calling the method 2wice, its creating flickering effect.
i.e. countdown(element, 50, 0);
it count downs but if i call it again i.e. countdown(element, 35, 0); it is flicks showing both the countddowns
You need to cancel the interval when the plugin initializes if you are going to call it on the same element. Otherwise you are running two intervals at once.
I'd suggest returning the interval from your function and allowing yourself to pass that interval in as a parameter. That way you can always cancel the interval before starting it (in case there is already one going). If you pass null for the interval var, you can still run clearInterval() without throwing errors.
For example:
function countdown(element, minutes, seconds, interval) {
// set time for the particular countdown
var time = minutes*60 + seconds;
clearInterval(interval);
return setInterval(function() {
...
Your first call could be:
var savedInterval = countdown('some-ele-id', 1, 1, null);
And your second call could be:
var interval = countdown('some-ele-id', 1, 1, savedInterval);
Another solution would be to save the interval as a global variable and cancel it without passing it as a parameter inside your plugin.
An alternative to avoid modify your code is:
var interval;
...
function countdown(element, minutes, seconds) {
// set time for the particular countdown
var time = minutes*60 + seconds;
interval = setInterval(function() {
...
And in your second call:
clearInterval(interval);
countdown(element, 35, 0);

Executing code inside setInterval function only once per few seconds

I'm working on a simple project that is HTML and Javascript; and I have a problem with my timer.
I'm calculating the seconds between two Date() objects; and every 2 seconds, I want to get a new random number. I have a setInterval that runs every 100 ms and when I get past the 2 second mark, the code inside the if statement should run.
So my question is:
How can I make sure the code execute only once per 2 seconds in an if statement that is inside a setInterval() that runs every 100 ms?
Here is the code:
var startTime = new Date();
var endTime = new Date();
var randomNumber = 0;
var gameTimer = setInterval(function(){
//calculate seconds;
var secondsPassed = Math.round( (endTime - startTime) / 1000 );
if(modulo(secondsPassed,2) == 0){
//when the "gate" is open this keep executing every 100 mili seconds.
//but i want it to execute only once every 2 seconds.
randomNumber = Math.floor(Math.random()*lanes.length);
$(lanes[randomNumber]).append(box);
}
endTime = new Date();
}, 100);
var modulo = function (n, m) {
var remain = n % m;
return Math.floor(remain >= 0 ? remain : remain + m);
};
I think you are asking for a double-interval timer.
var interval = 100, beat = 2000, ticks = 0;
var timer = setInterval(function(){
runsEvery100ms(); // ««« Code here runs every 100 ms.
if (ticks > 0 && ticks % beat === 0) {
runsEvery2000ms(); // ««« Code here runs every 2000 ms.
ticks = 0;
}
ticks += interval;
}, interval);
Demo Fiddle here.

Categories