Josh
Josh

Reputation: 25

Javascript while loop makes the page not load

When I put this in my header:

<script>
function checkiffinished() {
  var n = $('.result-row').length;
  while (n!==3)
  {
  n = $('.result-row').length;
  $("span").text("There are " + n + " divs.");
  };

  };
</script>

Then in the body put

<script>
 checkiffinished();
 </script>

then the page crashes.

The code is supposed to count the number of divs with the "result-row" class and repeat that until the number of divs with aforementioned class is 3.

How can I make it so as such and not crash the page?

EDIT 1: other jQuery I have in the page causes there to be .result-row elements on another event, that's why I need it to check periodically.

EDIT2 : I'm trying to run this in parallel with some other jQuery that manipulates the elements on the page.

Upvotes: 2

Views: 6974

Answers (4)

jfriend00
jfriend00

Reputation: 707686

Your code is an infinite loop if n !== 3 because nothing you do in the while loop ever changes the value of n so the while loop just runs forever waiting for the value of n to become 3. It is unclear why you put it in a while loop. It looks to me like it should just be an if instead of a while.

<script>
function checkiffinished() {
  var n = $('.result-row').length;
  if (n!==3)
  {
    $("span").text("There are " + n + " divs.");
  };

}
</script>

If you are going to use a while loop, then you have to have something that actually changes the value of n in the loop and code that ensures that you will reach the condition in your while loop to prevent the infinite loop.

As others have said, if you want to regularly check for the value of 3, then you need to repeatedly execute this function using setTimeout or setInterval not just loop infinitely. But, you don't want to execute it to often or you may drag down the performance of your site and other pages in the browser.

The best performing way to implement this would be just manually call checkiffinished() any time you've modified the page. That way, no browser cycles would be wasted regularly checking the page value when nothing has changed and the page would be updated immediately after the change (no waiting for the next timer to fire to check the page).

Upvotes: 1

shawndumas
shawndumas

Reputation: 1423

Your problem is that n is not decremented.

pimvdb's Idea is a good one. Here is an implementation that includes a callback:

 var waitUntil = function (fn, condition, interval) {
    interval = interval || 100;

    var shell = function () {
            var timer = setInterval(
                function () {
                    var check;

                    try { check = !!(condition()); } catch (e) { check = false; }

                    if (check) {
                        clearInterval(timer);
                        delete timer;
                        fn();
                    }
                },
                interval
            );
        };

    return shell;
};

Use it like this:

waitUntil(
  function () {
    // the code you want to run here...
  },
  function() {
    // the code that tests here... (return true if test passes; false otherwise)
  },
  0 // amout to wait between checks
)();

Upvotes: 2

pimvdb
pimvdb

Reputation: 154888

JavaScript can only run one piece of code at a time. So your while loop is clogging up all JavaScript execution. As a result, any code that adds elements is suspended - basically forever.

Instead, you might want to use an interval which checks e.g. each second: http://jsfiddle.net/pimvdb/sbs6m/1/.

function checkiffinished() {
  var n = $('.result-row').length;
  $("span").text("There are " + n + " divs.");
  if(n === 3) {
    // do something
    clearInterval(interval);
  }
};

var interval = setInterval(checkiffinished, 1000); // 1000 ms = 1 second

Upvotes: 10

Will Evans
Will Evans

Reputation: 227

Urmm, try making a button and see if it calls it and doesn't crash e.g <input type="button" value="Click me!" onclick="checkiffinished()" />

Upvotes: 0

Related Questions