Home > Net >  In a loop, innerHTML inserts only the last element called
In a loop, innerHTML inserts only the last element called

Time:04-18

Good morning,

I'm trying to display a countdown in several div tags with the same classes. But the problem is that only the last tag of the list contains the countdown.

Here is code :

    const contentsDownDate = document.querySelectorAll(".countDown");
nbElement = contentsDownDate.length-1;
for(var i = 0; i < nbElement; i  )
{
  var countDownDate = new Date("Jan 5, 2024 15:37:25").getTime();
 
  // Update the count down every 1 second
  x = setInterval(function() {
 
    // Get today's date and time
    var now = new Date().getTime();
       
    // Find the distance between now and the count down date
    var distance = countDownDate - now;
       
    // Time calculations for days, hours, minutes and seconds
    var days = Math.floor(distance / (1000 * 60 * 60 * 24));
    var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
    var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
    var seconds = Math.floor((distance % (1000 * 60)) / 1000);
       
    // Output the result in an element with id="demo"
    contentsDownDate[i].innerHTML = days   "d "   hours   "h "
      minutes   "m "   seconds   "s ";
       
    // If the count down is over, write some text
    if (distance < 0) {
      clearInterval(x);
      contentsDownDate[i].innerHTML = "EXPIRED";
    }
  }, 1000);
}

I did the same thing by calling ids but still the same result, only the last id displays the countdown.

What can I do to solve this problem ?

Note that the countdown code is taken from this: w3schools

PS: I also read that innerHTML prints at the end of the loop so it only prints the last tag and so you have to stop/pause the loop to print, especially with "setInterval", but I already did it. Unless this one was to update the countdown time? But in that case where should I place the other "setIntval"?

CodePudding user response:

The reason why this is not working is because you enter the infinite loop in a blocking state, meaning that the interval is never entered as the browser is busy looping. Imagine the browser can only do one thing at a time, as in a single thread, so the loop is it, and cannot do anything else until it's done, and in your case it never.

Basically, if you put a setInterval() inside loop without clear it then the setInterval never stop and that mean the loop is infinite so it never complete.

Instead of that, put the loop inside the setInterval() will do the job. Let try this:

const contentsDownDate = document.querySelectorAll(".countDown");
nbElement = contentsDownDate.length-1;
var countDownDate = new Date("Jan 5, 2024 15:37:25").getTime();

 // Update the count down every 1 second
 x = setInterval(function() {
   for (i=0; i<=nbElement; i  ){
   // Get today's date and time
   var now = new Date().getTime();
      
   // Find the distance between now and the count down date
   var distance = countDownDate - now;
      
   // Time calculations for days, hours, minutes and seconds
   var days = Math.floor(distance / (1000 * 60 * 60 * 24));
   var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
   var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
   var seconds = Math.floor((distance % (1000 * 60)) / 1000);
      
   // Output the result in an element with id="demo"
   contentsDownDate[i].innerHTML = days   "d "   hours   "h "
     minutes   "m "   seconds   "s ";
      
   // If the count down is over, write some text
   if (distance < 0) {
     clearInterval(x);
     contentsDownDate[i].innerHTML = "EXPIRED";
   }
}
 }, 1000);
  • Related