递归 setTimeout() 在后台暂停

发布于 2024-12-29 07:30:15 字数 474 浏览 1 评论 0原文

我有一段代码:

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 在选项卡处于后台状态时暂停此计时器,然后返回该选项卡时的问题,它会闪烁背景中错过的所有闪烁。

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

I have a piece of code:

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();

All it makes is blinking a picture once in ~30 seconds (time is less here for easier debugging)

The problem that Chrome pauses this timer while the tab in backgrounded, and then, when coming back to that tab, it blinks all the blinks that were missed in background.

I'd like to pause the timer while in background, but I don't know how. I've read some related posts, but it seems that they describe the opposite problem. Is there any way to detect the backgrounding of a tab?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧伤慢歌 2025-01-05 07:30:15

这是一个已知的功能。为了节省资源,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:代码已更新,并进行了下面讨论的优化。

It is a known feature. To conserve the resources Chrome does not update the window without focus :) You could check, for example, that window lost its focus and stop the timer. Start it again when window is in focus. For example:

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

Something like this. On one of my pages with animation a had the same problem with setInterval, so I just pause it when the page is in background.

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

And than skipped animation based on the value of paused flag.

ps: Code is updated with optimization discussed below.

以往的大感动 2025-01-05 07:30:15

Chrome、Firefox 和 IE10 具有页面可见性 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

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

Chrome, Firefox and IE10 have page visibility APIs that you can use to determine when you page is no longer visible. This works better than using focus in some circumstances. Here's an example from MDN:

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

And, some reference documents:

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

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

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

The only work-arounds I've seen for older browsers involve determining whether your window has focus or not which isn't perfect, but maybe better than nothing in some cases.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文