Home > Mobile >  Counter not displaying each number, just shows final total
Counter not displaying each number, just shows final total

Time:12-04

Why is it that the counter only shows final number vs seeing each number 1 by 1. What needs to be done to accomplish this?

var counter = 100;
function countdown() {

 while(counter < 1000) {
    
    counter  ;
    console.log(counter);
    document.getElementById('cc').innerHTML = counter;

  }
}
    
countdown();
setInterval(countdown, 1000);

CodePudding user response:

It's because you were using a while loop, instead use an if statement to check whether the counter has reached 1000. See below:

var counter = 100;
function countdown() {

 if(counter < 1000) {
    counter  ;
    console.log(counter);
    document.getElementById('cc').innerHTML = counter;
    

  }
}
    
countdown();
setInterval(countdown, 1000);
<div id="cc"></div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

You are not giving the browser time to breathe

Also why have a loop when setInterval loops?

And you want to count down. not up I guess

Lastly we can save a bracket

var counter = 10; // 10 to show it works
const cc = document.getElementById('cc');

function countdown() {
  if (counter === 0) { 
    cc.innerHTML = "DONE!";
    return
  }  
  //  console.log(counter);
  cc.innerHTML = counter;
  counter--;
}
countdown();
setInterval(countdown, 1000);
<span id="cc"></span>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

This problem is happening because the Javascript execution and page rendering are actually occurring in the same execution thread. This means that while the code is executing the browser will not be redrawing the page because running JavaScript blocks the updating of the DOM like in your example.

To solve this you can use the setTimeout() which allows you to specify a function that will be executed once after a set number of milliseconds. Now, there will be gaps in between the code execution in which the browser will get the chance to redraw the page. now, when you actually pass 0 as the the delay argument. it will schedule the callback to be run asynchronously, after the shortest possible delay - which will be around after JavaScript thread of execution is not busy (the callback function will be waiting in the callback queue to be pulled by the event loop to be handled after a really short time)

function count() {
   var counter = 100;
   var max = 1000;

   function timeoutLoop() {
      document.getElementById('cc').innerHTML = counter;
      if (  counter < max){
         setTimeout(timeoutLoop, 0);
      }
   }

   setTimeout(timeoutLoop, 0);
}

count();
<div id="cc">

</div>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

More about the event loop - https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop

Great article about browser rendering - https://developpaper.com/the-process-of-browser-rendering-web-pages/

  • Related