danjonescidtrix danjonescidtrix - 20 days ago 5
Javascript Question

each() loop with random setInterval

I am creating a page that I ultimately want to loop through each element with the ".binary" class.

Each element will change it's text value on a random setInterval time between 200-1000. At the moment I have:

$(function () {
$(".binary").each(function (i , obj) {
setTimeout(function () {
if (obj.innerText == 0) {
obj.innerText = 1;
} else {
obj.innerText = 0;
}
}, 500);
});
});


When I run this code it only seems to run once then stops. Is there a way I can constantly loop these individually, so the elements individually change at a random set time?

Any help or advice is appreciated. Thank you in advance.

Answer

The issue is your use of a loop. The combination of this code and that in your previous (now deleted) question, means that you're stacking up thousands of timers per second, hence the browser locks up. Also note that within the scope of the setTimeout() function, this will be the window, not the .binary element.

To fix this you could store the index of the current element in a variable and increment that after the expiration of each timer. Something like this:

function flipValue(index) {
  setTimeout(function() {
    var $binary = $('.binary');
    $binary.eq(index % $binary.length).text(function(i, t) {
      return t == '1' ? '0' : '1';
    });
    flipValue(++index);
  }, Math.round(Math.random() * 800) + 200); // random between 200 - 1000
};

flipValue(0);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="binary">0</div>
<div class="binary">1</div>
<div class="binary">0</div>
<div class="binary">1</div>

If I wanted to apply this function to all the binary numbers at the same time, how would I do this?

In this case you just need to remove the references to index and the eq() method call:

function flipValue() {
  setTimeout(function() {
    $('.binary').text(function(i, t) {
      return t == '1' ? '0' : '1';
    });
    flipValue();
  }, Math.round(Math.random() * 800) + 200); // random between 200 - 1000
};

flipValue();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="binary">0</div>
<div class="binary">1</div>
<div class="binary">0</div>
<div class="binary">1</div>

Comments