-1

Basically I wanted to make a countdown with javascript, following my logic the code below should work, but for unknown reason it is not working. Could someone help me to figure out what's wrong with the code? It's kind of annoying.

function startCounter(time)
{
    var counter= document.getElementById("counter").innerHTML;
    var min=0;

    setTimeout(function()
    {
        for(i = 0; i < time; i++)
        {
            document.getElementById("counter").innerHTML = min+ ":" +i;

            if(i == 59) {
                min++;
                i = 0

                document.getElementById("counter").innerHTML = min+ ":" +i; 
            } 
        }
    }, 1000)
};

startCounter(89);
<p id="counter">0:00</p>
Liam
  • 27,717
  • 28
  • 128
  • 190
Ignorant23
  • 101
  • 7

6 Answers6

2

You are creating an infinite loop.

You are wrapping this part:

if(i == 59) {
    min++;
    i = 0

    document.getElementById("counter").innerHTML = min+ ":" +i; 
}   

in a for loop that uses i as a limiter. Each time the i reaches 59, you are resetting it back to 0, and the loop continues.

// Add your code here

function startCounter(time)
{
    var counter= document.getElementById("counter").innerHTML;
    var min = parseInt(time / 60);
    var seconds = time % 60;

    setInterval(function()
    {
         
        seconds++;
         
         document.getElementById("counter").innerHTML = min+ ":" +seconds;

            if(seconds == 60) {
                min++;
                seconds = 0

                document.getElementById("counter").innerHTML = min+ ":" +seconds; 
            } 

    }, 1000)
};

console.log("Start");

startCounter(89);
<p id="counter">

</p>
Wouter Coebergh
  • 804
  • 1
  • 6
  • 20
0

You have a couple options that would work. Calling the startCounter again from inside your setTimeout function or my favourite way is window.setInterval.

    var p = document.getElementById("count");
  
  function startTimer(time){
    var num = 0; // the increment number
    var intervalId = window.setInterval(function(){
      num += 1; // increment the number
      if(num == time){
        window.clearInterval(intervalId);
        // you can run your callback here after the timer reached your goal
        startTimer(num + 1); // this just adds a second and restarts the timer as a example
      }
      p.innerText = num;
    }, 1000);
  }
  
  // Start the timer here
  startTimer(10);
<p id="count"></p>
Trevor Reimer
  • 304
  • 2
  • 14
  • The OP wants to count upwards – Liam Jun 27 '18 at 14:52
  • I corrected it to function correctly now. @Ignorant23 may I suggest using a approach like this instead of the setTimeout? You can read on why here. https://stackoverflow.com/a/729943/8993140 – Trevor Reimer Jun 27 '18 at 15:07
  • I see the counter counting up on my end. Must be stackOverFlow being fidgety. Try this fiddle https://jsfiddle.net/szL1gc6a/ – Trevor Reimer Jun 27 '18 at 15:17
0

The issue is with this line:

for(i=0;i<time;i++) {

You have an infinite loop if your time is > 59, because of this line:

if(i==59){
    //snip
    i=0
}

Since your function is never finishing setTimeout is never finishing and the browser doesn't appear to be updating your element.

Michael Powers
  • 1,970
  • 1
  • 7
  • 12
0

Don't set i back to zero, so your for(true) condition ist always true and your loop can't stop.

function startCounter(time)
{
    var counter= document.getElementById("counter").innerHTML;
    var min=0;

    setTimeout(function()
    {
        for(i = 0; i < time; i++)
        {
            document.getElementById("counter").innerHTML = min+ ":" +i;

            if(i == 59) {
                min++;

                document.getElementById("counter").innerHTML = min+ ":" +i; 
            } 
        }
    }, 1000)
};

startCounter(89);
<p id="counter">0:00</p>
  • I don't think you want to run through the entire for loop with each call to setTimeout. – Mark Jun 27 '18 at 14:53
0

var timer;
var i = 0; 
var counter = document.getElementById("counter");
var min = 0;
var targetTime = 5;
 
function startCounter(){
 
 if(min < targetTime){
  if(i == 59){
   min++;
   i = "00";
  } else {
   i++;
   if (i < 10) {
    i = "0"+i;
   }
  }
  counter.innerHTML = min + ":" + i;
 } else {
  clearInterval(timer);
 }
 
}

timer = setInterval(startCounter, 1000);
<p id="counter"></p> 
Gabor
  • 566
  • 5
  • 14
0

You have a couple of problems... you seem to be trying to iterate seconds inside the callback that will be executed once every second.

Even if you fixed that code, you're going to have a problem with the fact that setTimeout does not execute exactly at the specified value. It fires whenever the thread can queue the task > the time scheduled. So your timer is going to drift over it's duration.

I'd recommend the below approach. Using a requestAnimationFrame loop (you could also use an interval) check the difference in the JavaScript clock between the time you started and now and then print the difference.

var firstTime;
function startTimer(){
  firstTime = Date.now();
  runTimer();
}
function runTimer(){
  var diff = Date.now() - firstTime;//value in milliseconds since the timer started.
  var sec = Math.floor((diff/1000)) % 60;//constrain to seconds
  var min = Math.floor(diff/(1000 * 60));//minutes
  document.getElementById('timer').innerHTML = min + ":"+(String(sec)).padStart(2,"0");
  requestAnimationFrame(runTimer);
}
startTimer();
<div id="timer">0:00</div>
dgeare
  • 2,618
  • 5
  • 18
  • 28