When using setInterval, if I switch tabs in Chrome and come back, the slider will go crazy, catching up

I have a jQuery slider on my site, and the code going to the next slide is in a function called nextImage. I used setInterval to run my timer function, and it does exactly what I want: it runs my timer slides. BUT, if I go to the site in Chrome, switch to another tab and return it, the slider will continuously go through the slides until it “catches”. Does anyone know how to fix this. Below is my code.

setInterval(function() { nextImage(); }, 8000); 
+45
javascript jquery google-chrome slider
May 31 '11 at 5:44
source share
6 answers

How to determine when a tab is concentrated or not in Chrome using Javascript?

 window.addEventListener('focus', function() { document.title = 'focused'; },false); window.addEventListener('blur', function() { document.title = 'not focused'; },false); 

To apply to your situation:

 var autopager; function startAutopager() { autopager = window.setInterval(nextImage, 8000); } function stopAutopager() { window.clearInterval(autopager); } window.addEventListener('focus', startAutopager); window.addEventListener('blur', stopAutopager); 

Please note that the latest version of Chromium has either an error or a “function” that makes it less reliable, requiring the user to click at least once anywhere in the window. See the related question above for details.

+38
May 31 '11 at 7:19
source share

I am writing the answer here: How to make setInterval work when the tab is inactive in Chrome?

Just do the following:

 setInterval(function() { $("#your-image-container").stop(true,true); nextImage(); }, 1000); 

Inactive browser tabs contain some setInterval or setTimeout functions. stop (true, true) - stops all buffered events and imperceptibly only the last animation.

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

+15
Sep 12 '11 at 12:46 on
source share

The thought comes to mind:




Idea number 1

You can make the short package idempotent . For example, you can say:

 function now() { return (new Date()).getTime(); } var autopagerInterval = 8000; function startAutopager() { var startImage = getCurrentImageNumber(); var startTime = now(); var autopager = setInterval( function() { var timeSinceStart = now() - startTime(); var targetImage = getCurrentImageNumber + Math.ceil(timeSinceStart/autopagerInterval); if (getCurrentImageNumber() != targetImage) setImageNumber(targetImage); // trigger animation, etc. }, autopagerInterval ); return autopager; } 

Thus, even if the function is run 1000 times, it will be executed in just a few milliseconds and the animation only once.

note . If the user leaves the page and returns, it will be scrolled. This may not be what the original poster wants, but I leave that decision because sometimes this is what you want.




Idea number 2

Another way to add idempotence (while preserving the nextImage() function and not scrolling at the bottom of the page) was to set the mutex lock function, which disappears after a second (cleared by another timeout), Thus, even if the setInterval function was called 1000 times, only the first instance was launched, and the rest did nothing.

 var locked = false; var autopager = window.setInterval(function(){ if (!locked) { locked = true; window.setTimeout(function(){ locked=false; }, 1000); nextImage(); } }, 8000); 

edit: this may not work, see below




Idea number 3

I tried the following test:

 function f() { console.log((new Date()) + window.focus()); window.setTimeout(f, 1000); } f(); 

This seems to indicate that the function is being called every second. This is strange ... but I think this means that the calling calls are being called, but that the page renderer refuses to refresh the page in any graphical way until the tab is focused, delaying all operations until the user returns, but operations continue piles up.

Also, the window.focus() function does not indicate whether the focus has focus; it OPENS focus on the window and therefore does not matter.

We probably want this: How to determine when a tab is concentrated or not in Chrome using Javascript? - you can turn off your interval when the window loses focus (blur) and reset when it receives focus.

+6
May 31 '11 at 6:20
source share

I don’t know exactly what is going on in your nextImage () function, but I had a similar problem. I used animation () with setInterval () on the jQuery image slider that I created, and I experienced the same thing as you did when I switched to another tab and back. In my case, the animate () function was queued, so as soon as the window returns focus, the slider will go crazy. To fix this, I just stopped the animate () function from the queue.

There are several ways to do this. the easiest is with .stop (), but this problem and how to fix it are documented in jQuery docs. Check out this page at the bottom under the heading of additional notes: http://api.jquery.com/animate/

+1
Aug 09 2018-11-11T00:
source share

I ran into a similar problem, as this code below works fine for me.

  var t1= window.setInterval('autoScroll()', 8000); window.addEventListener('focus', function() { focused = true; window.clearInterval(t1); t1 = window.setInterval('autoScroll()', 8000); },false); window.addEventListener('blur', function() { focused = false; window.clearInterval(t1); },false) function autoScroll() { if ( running == true){ if ( focused = true){ forwardSlide(); } } else { running = true; } } 
0
Jul 29 '11 at 12:32
source share

If you use the Soh Tanaka image slider, just add this ... to solve the problem with Google Chrome:

$(".image_reel").stop(true, true).fadeOut(300).animate({ left: -image_reelPosition}, 500 ).fadeIn(300);

Pay attention to the .stop () function. Ignore the fade in and out that I used in my version

thank

0
Sep 14 '11 at 15:54
source share



All Articles