我的网站上有一个 jQuery 滑块,下一张幻灯片的代码位于名为 nextImage 的函数中。我使用 setInterval 在计时器上运行我的函数,它完全符合我的要求:它在计时器上运行我的幻灯片。但是,如果我在 Chrome 中访问该站点,切换到另一个选项卡并返回,滑块会连续运行幻灯片,直到它“赶上”。有谁知道解决这个问题的方法。以下是我的代码。
setInterval(function() {
nextImage();
}, 8000);
我的网站上有一个 jQuery 滑块,下一张幻灯片的代码位于名为 nextImage 的函数中。我使用 setInterval 在计时器上运行我的函数,它完全符合我的要求:它在计时器上运行我的幻灯片。但是,如果我在 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 中,存在一个错误或“功能”使其不太可靠,要求用户至少在窗口中的任何地方单击一次。有关详细信息,请参阅上面的链接问题。
我在这里发布了一个答案:当 Chrome 中的选项卡处于非活动状态时,如何使 setInterval 也能工作?
只需这样做:
setInterval(function() {
$("#your-image-container").stop(true,true);
nextImage();
}, 1000);
非活动浏览器选项卡会缓冲一些 setInterval 或 setTimeout 函数。stop(true,true) - 将停止所有缓冲事件并仅立即执行最后一个动画。
window.setTimeout() 方法现在限制为在非活动选项卡中每秒发送不超过一个超时。此外,它现在将嵌套超时限制为 HTML5 规范允许的最小值:4 毫秒(而不是它过去用于限制的 10 毫秒)。
想到了几个想法:
您可以使短脉冲具有幂等性。例如,你可以说:
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 次,它仍然会在几毫秒内运行并且只动画一次。
注意:如果用户离开页面并返回,它将滚动。这可能不是原始海报想要的,但我留下这个解决方案,因为它有时是你想要的。
添加幂等性的另一种方法(同时仍然保持您的nextImage()
函数并且不让它滚动到页面底部)是让函数设置一个互斥锁,该锁在一秒钟后消失(由另一个超时清除)。因此,即使 setInterval 函数被调用 1000 次,也只有第一个实例会运行,其他实例什么也不做。
var locked = false;
var autopager = window.setInterval(function(){
if (!locked) {
locked = true;
window.setTimeout(function(){
locked=false;
}, 1000);
nextImage();
}
}, 8000);
编辑:这可能不起作用,见下文
我尝试了以下测试:
function f() {
console.log((new Date()) + window.focus());
window.setTimeout(f, 1000);
}
f();
它似乎表明该函数每秒被调用一次。这很奇怪......但我认为这意味着回调都被调用,但该页面渲染拒绝任何图形化的方式来更新页面,而标签是没有重点,延缓所有的操作,直到用户返回,但操作保持打桩向上。
该window.focus()
函数也不会说明窗口是否具有焦点;它将焦点放在窗口上,因此无关紧要。
我们想要的可能是这样的:如何使用 Javascript 检测 Chrome 中的选项卡何时聚焦或不聚焦?-- 您可以在窗口失去焦点(模糊)时取消设置间隔,并在获得焦点时重置间隔。
我不知道你的函数 nextImage() 到底发生了什么,但我遇到了类似的问题。我在我创建的 jQuery 图像滑块上使用 animate() 和 setInterval(),当我切换到不同的选项卡并再次返回时,我遇到了与您相同的事情。在我的例子中 animate() 函数正在排队,所以一旦窗口重新获得焦点,滑块就会发疯。为了解决这个问题,我只是停止了 animate() 函数的排队。
有几种方法可以做到这一点。最简单的方法是使用 .stop(),但是这个问题和修复它的方法记录在 jQuery 文档中。在标题附加说明下检查底部附近的此页面: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;
}
}