当使用setInterval时,如果我在Chrome中切换标签并返回,则滑块变得疯狂追赶

我在我的网站上有一个jQuery滑块,去下一张幻灯片的代码是一个名为nextImage的函数。 我用setInterval在计时器上运行我的function,它正是我想要的:它在计时器上运行我的幻灯片。 但是,如果我在Chrome浏览器中访问该网站,切换到另一个选项卡并返回,则滑块会不断滑过幻灯片,直到“追上”为止。 有谁知道一种方法来解决这个问题。 以下是我的代码。

setInterval(function() { nextImage(); }, 8000); 

如何检测一个选项卡的重点或不使用JavaScript的Chrome?

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

适用于您的情况:

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

请注意,在最新版本的Chromium中,有一个bug或者一个“特性”,使得这个不太可靠,要求用户至less在窗口的任何地方点击过一次。 有关详细信息,请参阅上面的链接问

我在这里发布一个答案: 我怎样才能使setInterval也工作,当一个选项卡在Chrome中处于非活动状态?

只要这样做:

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

不活动的浏览器选项卡缓冲一些setInterval或setTimeout函数。 停止(true,true) – 将停止所有缓冲事件并仅执行最后一个animation。

window.setTimeout()方法现在限制在非活动选项卡中每秒发送一次超时。 另外,它现在将嵌套的超时设置为HTML5规范允许的最小值:4 ms(而不是用来钳位的10 ms)。

想到一些想法:


想法#1

你可以这样做,以便短时间爆发是幂等的 。 例如,你可以说:

 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; } 

这样即使函数运行了1000次,它仍然只能运行几毫秒,而且只能animation一次。

注意 :如果用户离开页面并返回,它将会滚动。 这可能不是原来的海报所需要的,但我留下这个解决scheme,因为它有时是你想要的。


想法#2

另一种方法来添加幂等(虽然仍然保持你的nextImage()函数,而不是让它滚动到页面的底部)将该函数设置一个互斥锁秒后消失(由另一个超时清除)。 因此,即使setInterval函数被调用了1000次,也只有第一个实例会运行,而其他的则不会执行任何操作。

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

编辑:这可能无法正常工作,请参阅下文


想法#3

我试了下面的testing:

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

这似乎表明,函数每秒都在调用。 这很奇怪……但我认为这意味着callback被调用,但是页面渲染器在选项卡未聚焦时拒绝以任何graphics方式更新页面,延迟所有操作直到用户返回,但操作继续打桩向上。

另外window.focus()函数不会说窗口是否有焦点; 它专注于窗口,因此是无关紧要的。

我们想要的可能是这样的: 如何检测一个选项卡是否在使用Javascript的Chrome浏览器中关注? – 当窗口失去焦点(模糊)时,您可以取消设置间隔,并在获得焦点时将其重置。

我不知道在你的函数nextImage()中到底发生了什么,但是我有类似的问题。 我在我创build的jQuery图像滑块上使用了setInterval()方法的animate(),当我切换到另一个选项卡并返回时,我遇到了同样的情况。 在我的情况下,animate()函数正在排队,所以一旦窗口重新聚焦滑块将发疯。 要解决这个问题,我只是停止排队的animate()函数。

有几种方法可以做到这一点。 最简单的是.stop(),但是这个问题和解决方法在jQuery文档中有logging。 检查此页面附近底部的标题附加说明: http : //api.jquery.com/animate/

我遇到了类似的问题,不知何故,下面的代码对我来说工作得很好。

  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; } } 

如果您正在使用Soh Tanaka的图片滑块,那么只需添加…来解决您的Google Chrome问题:

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

记下.stop()函数。 忽略淡入淡出的东西,这就是我用我的版本

谢谢