递归setTimeout()在后台暂停

recursive setTimeout() pause on background

本文关键字:后台 暂停 setTimeout 递归      更新时间:2023-09-26

我有一段代码:

var logo = $("#blinking-logo");
function logo_blink() {
    logo.fadeOut(10).delay(10)
        .fadeIn(10).delay(20)
            .fadeOut(10).delay(10)
            .fadeIn(10)
    window.setTimeout(logo_blink, (Math.random()*(1500))+1500);
}
logo_blink();

它只需要在大约30秒内闪烁一次图片(为了更容易调试,这里的时间更短)

问题是,Chrome在选项卡处于后台时暂停了此计时器,然后,当返回到该选项卡时,它会闪烁背景中错过的所有闪烁。

我想在后台暂停计时器,但我不知道怎么做。我读过一些相关的帖子,但它们似乎描述了相反的问题。有什么方法可以检测接线片的背面接地吗?

这是一个已知的特性。为了节省资源,Chrome不会在没有焦点的情况下更新窗口:)例如,您可以检查该窗口是否失去焦点并停止计时器。当窗口处于焦点时再次启动它。例如:

var timer = null;
var logo = $("#blinking-logo");
function logo_blink() {
    if(timer) clearTimeout('timer');
    logo.fadeOut(10).delay(10)
        .fadeIn(10).delay(20)
            .fadeOut(10).delay(10)
            .fadeIn(10)
    timer = window.setTimeout(logo_blink, (Math.random()*(1500))+1500);
}
logo_blink();
$(window).blur(function(){clearTimeout(timer); timer = null;});
$(window).focus(function(){if (!timer) timer = window.setTimeout(logo_blink, (Math.random()*(1500))+1500);});

像这样的东西。在我的一个带有动画的页面上,a的setInterval也有同样的问题,所以我只是在页面处于后台时暂停它。

if (!$.browser.msie)
{
    $(window).focus(function(){paused = false;});
    $(window).blur(function(){paused = true;});
}

并基于暂停标志的值跳过动画。

ps:代码将通过下面讨论的优化进行更新。

Chrome、Firefox和IE10都有页面可见性API,您可以使用这些API来确定页面何时不再可见。在某些情况下,这比使用焦点效果更好。下面是MDN的一个例子:

//startSimulation and pauseSimulation defined elsewhere
function handleVisibilityChange() {
    if (document.hidden) {
        pauseSimulation();
    } else  {
       startSimulation();
    }
}
document.addEventListener("visibilitychange", handleVisibilityChange, false);

以及一些参考文件:

http://code.google.com/chrome/whitepapers/pagevisibility.html

https://developer.mozilla.org/en/DOM/Using_the_Page_Visibility_API

W3文档:http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/PageVisibility/Overview.html

我在旧浏览器中看到的唯一解决方法是确定你的窗口是否有焦点,这并不完美,但在某些情况下可能总比什么都没有好。