【问题标题】:recursive setTimeout() pause on background递归 setTimeout() 在后台暂停
【发布时间】:2012-01-27 21:10:37
【问题描述】:

我有一段代码:

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 在标签页处于后台时暂停此计时器的问题,然后,当返回该标签页时,它会闪烁所有在后台错过的闪烁。

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

【问题讨论】:

标签: javascript jquery google-chrome settimeout


【解决方案1】:

这是一个已知功能。为了节省资源,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);});

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

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

然后根据暂停标志的值跳过动画。

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

【讨论】:

  • 为了避免在窗口获得焦点时也浪费CPU时间和内存,logo_blink()中的第一个表达式应该是if(timer) clearTimeout('timer');
  • 像魅力一样工作 =) 我会同意 Teemu 关于清除计时器的看法
  • @M2_ 可能是,谢谢提示:)我会更新代码。
【解决方案2】:

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

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

【讨论】:

  • 这似乎更复杂,但看起来像通用解决方案,特别是如果您不使用 jQuery 或其他东西。谢谢!
  • @M2_ - 它实际上不太通用(因为它只适用于现代浏览器),但它更准确。例如,当您有并排的浏览器窗口时,这有效,并且焦点方法会因此而混淆 - 它实际上只适用于未获得焦点的窗口永远不可见的选项卡。
  • 哦,这也是一个不错的方法。但是旧版浏览器是否在后台具有“时间冻结”机制?如果document.visible 仅适用于现代版本并解决了问题。我只是想知道问题和解决方案是否同时出现。
  • @M2_ - 我不明白你在问什么。如果您阅读了我包含的参考资料,它会解释哪些浏览器支持此功能。
猜你喜欢
  • 2019-03-08
  • 2019-10-01
  • 2011-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-27
  • 1970-01-01
相关资源
最近更新 更多