11

I've got a site with endlessly sliding images using jquery's setIntervall() function.

When calling the page in Chrome 13 and I switch to another tab to come back a few seconds later the image sliding is happening faster, as if it tried to keep up to where it was if it hadn't switched to another tab.

How could I resolve this issue?

$(window).load(function() { 
    setInterval(nextSlide, 3500);
});

function nextSlide(){   
    offset += delta;
    $("#slideContent").animate({left: -1 * offset}, 1000);
}
Jan Feldmann
  • 378
  • 5
  • 13
  • Why did you go with jfriend00's solution to turn the timer off when inactive, instead of nitek's solution to .stop() the queue? – mlhDev Nov 27 '11 at 00:32

5 Answers5

18

At the beginning I would like to apologize for all the mistakes - my English is not perfect.

The solution of your problem may be very simple:

$(window).load(function() { 
    setInterval(nextSlide, 3500);
});

function nextSlide(){   
    offset += delta;
    $("#slideContent").stop(true,true).animate({left: -1 * offset}, 1000);
}

inactive browser tabs buffer some of the setInterval or setTimeout functions. stop(true,true) - will stop all buffered events and execute immadietly only last animation. This problem will also appears in Firefox > 5.0 - read this article: Firefox 5 - changes

The window.setTimeout() method now clamps to send no more than one timeout per second in inactive tabs. In addition, it now clamps nested timeouts to the smallest value allowed by the HTML5 specification: 4 ms (instead of the 10 ms it used to clamp to).

here you can read, how animate works - it fires setInterval function many times. How animate really works in jQuery

nitka.pawel
  • 239
  • 1
  • 5
  • English is my native language and mine aint perfect either! Around here the question is how good your code is more so than your English. Don't worry too much about it. :-) – T.Rob Jul 27 '11 at 23:55
3

The latest versions of Chrome apparently slow down the operation of setInterval when a tabbed page is in the background and then when you bring that page forward it tries to catch up.

On the Chromium blog, Google said:

In the forthcoming Chrome 11 release, we plan to reduce CPU consumption even for pages that are using setTimeout and setInterval. For background tabs, we intend to run each independent timer no more than once per second. This change has already been implemented in the Chrome dev channel and canary builds.

Your interval is 3.5 seconds, but the animation itself may be using much shorter timers.

Possible ways to work-around it:

  • Stop your timer/animation when the window is not visible. Restart the timer/animation when the window becomes visible.
  • Instead of setInterval, use setTimeout and then just reset the setTimeout each time it fires to create your own repeating interval - though in your case, it may be jQuery's use of timers that are the issue - I don't know.
  • Slow your timers down so they don't run afoul of this (again might be inside of jQuery not your own timers).

The best option is probably to figure out when to just stop and then restart the animation.

Similar question here: Chrome: timeouts/interval suspended in background tabs?.

FYI, Chrome has new experimental API for detecting page visibility for just this reason. You can read about it here: http://code.google.com/chrome/whitepapers/pagevisibility.html. it helps solve the issue when your page is visible, but doesn't have focus.

Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • The one thing I've wondered about the "lose focus technique" is that the animation won't run when the web page is in a separate window and fully visible, but not the window with the focus. That won't happen if the user uses tabs, but can happen if they have multiple browser windows open on a large enough screen that those windows can both be visible. What you really want to know is if it's visible. – jfriend00 Jul 18 '11 at 19:46
  • I added (to my answer above) a reference to the Chrome page visibility API. – jfriend00 Jul 18 '11 at 23:52
0

Have you tried not using setInterval or setTimeout at all, but just use the complete function of the animate function to kick off the next slide? The delay function is set to 2500 ( i.e. 1000 for the animate subtracted from the 3500 of the setInterval). I haven;t tried this with Chrome, so please let me know if it works.

var slider = function(n){
    $("#slideContent").delay(2500).animate({left: -1 * n * delta},
                                           1000,
                                           function(){slider(n+1)}
                                          );
};
slider(1);
user229044
  • 232,980
  • 40
  • 330
  • 338
Neil
  • 3,229
  • 1
  • 17
  • 15
  • Thanks for your answer. I went with turning the timer off when switching to another tab, but I will test your code tomorrow to let you know if it works. – Jan Feldmann Jul 18 '11 at 18:43
  • Christian, Thanksfor that - glad to know that you have a solution. Regards – Neil Jul 18 '11 at 18:49
  • Thanks for the info. Most people use setTimeout/setInterval for repeated animation, but I've found that useing "delay()" along with the callback mechanism of "animate" or the other animation functions normally work just as well, in some cases better. Regards – Neil Jul 20 '11 at 13:59
0

Hey are you using Jquery 1.6?

This may be the cause since 1.6 uses requestAnimationFrame for animations. You may want to check this page out for a replacement for setInterval, clearInterval

http://blog.blenderbox.com/2011/06/24/jquery-1-6-1-and-setinterval/

code: https://gist.github.com/1002116 [edit: updated source, edit2: currently doesnt work with firefox due to firefox bug. -- I had do downgrade to JQuery 1.5]

From the blogger:

Then, where you were calling setInterval(func, poll), you now call requestInterval(func, poll). Where you call clearInterval(interval), you now call clearRequestInterval(interval);

ken
  • 1
  • 1
0

try setInterval() it works

<script type="text/javascript" src="js/jquery-1.5.js"></script>
        <script type="text/javascript">
            var i=1;
            $(document).ready(function(){
                slideShow();
                $("#next").click(function(){
                    slideShow();
                });
            });
            function slideShow(){
                if(i<3){
                    $("#slide-container").animate({ left:"+=35px" }, {  duration:500})
                    $("#slide-container").animate({ left:"-=735px" }, {  duration:250})
                    i++;
                }
                else {
                    $("#slide-container").animate({ left:"+=1400px" }, {  duration:1000})
                    i=1;
                }
                setTimeout('slideShow()',2000);
            }
    </script>
dippas
  • 58,591
  • 15
  • 114
  • 126