2

I have a codepen demo that I've worked up that uses several instances of setTimeout and setInterval. I've found that there's an issue with setInterval if the user leaves the page.

You may notice that if you leave the page while this interval is running, the numbers will continue to increment forever. The interval is essentially not getting cleared. This works just fine otherwise.

Here's an example of one of the instances of setInterval within a setTimeout.

setTimeout(function() {
  var x = parseInt($one.text());

  handle = setInterval(function() {
    if (x > -5) {
      x--;
      $one.html(x + 'px');
    }
    else {
      clearInterval(handle);
      handle = null;
    }
  }, 200);

  $box.animate({
    boxShadow: '-5px 0 0 0 #333'
  }, 2000);

}, 7000);

I've tried adding both clearInterval(handle) and handle = null in my if/else statement, but I simply can't get the interval to clear if a user leaves the page. Any other ways I can approach this setInterval? Is this just a javascript limitation?

Update

Strangely enough, when I log the x value, the console shows it displaying the -1 through -4 numbers correctly. Does clearInterval not run from another window?

Brian Phillips
  • 4,302
  • 2
  • 25
  • 40
  • look at how the browsers handle off tab timers. iirc they never stop they just slow down. – rlemon Oct 16 '13 at 14:07
  • @rlemon you're right - "When a tab is inactive, only at a maximum of once per second the function is called." from [this question](http://stackoverflow.com/questions/6032429/chrome-timeouts-interval-suspended-in-background-tabs). Interesting – Brian Phillips Oct 16 '13 at 14:11
  • 1
    As a side note: requestAnimationFrame completely stops when off tab. I realize it has nothing to do with this issue, but it is good to know :P – rlemon Oct 16 '13 at 17:06

1 Answers1

4

You can use setTimeout in place of setInterval like this :-

setTimeout(function() {
    var x = parseInt($one.text());
    function callOnTimeOut(){
        setTimeout(function() {
            if (x > -5) {
                x--;
                $one.html(x + 'px');
                callOnTimeOut();
            }
        }, 200);
    }
    callOnTimeOut();

    $box.animate({
        boxShadow: '-5px 0 0 0 #333'
    }, 2000);

}, 7000);
Shreyance Jain
  • 914
  • 7
  • 12
  • This does the trick. Chrome still slows down the `setInterval`, so it has to catch up if I leave the screen, but it doesn't overflow anymore :-) thanks! – Brian Phillips Oct 16 '13 at 15:00