0

I have a page with any number of div's and I need a separate timer for each div. I have setup this jsfiddle. The parts in the loop that deal with which timer are all set to timer 0 and when the script is ran, the first div is updated. But in this jsfiddle I have changed all of the references to item 0 to use the idx var and when ran none of the div's are updated. The code using idx is shown below. Would someone please point out where I'm going wrong?

    <div><span id="time-left-0">1.59</span></div>
    <div><span id="time-left-1">2.59</span></div>
    <div><span id="time-left-2">3.59</span></div>

    <script>
    var timer_ctr = 3;
    var timerID = Array(timer_ctr).fill(0);
    var timeLeft = Array(timer_ctr).fill(0);
    var idx;

    for (idx = 0; idx < timer_ctr; idx++) {

      if ($("#time-left-" + idx).length === 0) {
        clearInterval(timerID[idx]);
      } else {
        timerID[idx] = setInterval(function() {
          var ct = 0;
          var newtime = 0;

          if (timeLeft[idx]) { //timer has ran so just update the display
            ct = timeLeft[idx];
            newtime = ct - 0.01;
            if (newtime == 0.99) {
              newtime -= .40; //gives 59 seconds
            }
          } else {
            ct = $("#time-left-" + idx).text(); //get the string
            ct = ct.replace(":", "."); //make it appear as a float 
            ct = parseFloat(ct); //convert to float
            newtime = (ct == Math.floor(ct)) ? ct - 1 + .59 : ct - .01; //change to next second down
          }

          newtime = newtime.toFixed(2); //round it
          timeLeft[idx] = newtime; //save for next pass
          newtime = newtime.toString(); //convert to string for display
          var newtime_str = newtime.replace('.', ':'); //change to show separator for time

          if (newtime > 0) {
            $("#time-left-" + idx).text(newtime_str);
          } else {
            $("#time-left-" + idx).text('expired');
            clearInterval(timerID[idx]);
          }
        }, 1000);
      }
    }
    </script>
user3052443
  • 758
  • 1
  • 7
  • 22
  • 1
    `idx` is not scoped to the intervals you create. – Taplar Jun 18 '19 at 17:10
  • Doesn't idx being declared above the look and the loop enveloping all of the code mean that idx is global for all of that code? Also,can you provide a link to where this has been answered, please? I read through many threads but didn't find one regarding this problem. – user3052443 Jun 18 '19 at 18:08
  • *"mean that idx is global for all of that code"* yes, exactly, which means every interval will share the same variable, with the same value. Which once the loop is done, all the intervals will be using the same `idx` with a value of `3` (the value that terminates the loop) – Taplar Jun 18 '19 at 18:10
  • I can't figure out how to fix this. I need unique timer ID's, I think, and the only way I know how to do that is with a loop. And just to be clear, I mentioned that there could be any number of div's/timers. I'm obviously missing something simple but I don't have the experience to figure it out. Can you at least give me a hint as to how to assign unique ID's without a loop? – user3052443 Jun 19 '19 at 11:07
  • The duplicate covers this issue, both with the usage of `forEach` or the usage of `let`, as two possible approaches to a fix. – Taplar Jun 19 '19 at 14:00
  • I didn't realize a link to the duplicate thread was at the top, which is why I asked for it previously. But someone was kind enough to take the time to explain that to me. The thread provided a solution. Thank you for taking the time to bother with this. – user3052443 Jun 20 '19 at 11:18

0 Answers0