如果选项卡失去焦点,FireFox 中的 setInterval 循环出现 jQuery 动画问题

发布于 2024-12-05 02:28:18 字数 931 浏览 1 评论 0原文

我开发了一个小脚本,使用 jQuery 和 animate() 函数使文本看起来像是来自远方。 我有两个主要问题。第一个描述如下: Chrome 中的 Jquery 字体大小动画问题,太迟缓

第二个是我需要循环播放动画。我的方法效果很好,但在 FireFox 中,它实现了一种资源节省机制,当浏览器的选项卡窗口处于后台时,这会让事情变得很奇怪。

我很确定这个问题是已知的,并且关注您可以在 Jquery doc 上阅读的 animate() 内容:

由于 requestAnimationFrame() 的性质,您永远不应该使用 setInterval 或 setTimeout 循环对动画进行排队。为了节省CPU资源,支持requestAnimationFrame的浏览器在窗口/选项卡未显示时不会更新动画。如果在动画暂停时继续通过 setInterval 或 setTimeout 对动画进行排队,则当窗口/选项卡重新获得焦点时,所有排队的动画将开始播放。为了避免这种潜在的问题,请使用循环中最后一个动画的回调,或者将一个函数附加到 elements.queue() 来设置启动下一个动画的超时。

...但我无法理解如何将解决方案应用于我的脚本。

您可以在此处测试和使用代码:http://jsbin.com/ehahoc/7/

只需在一个选项卡上打开代码,然后从另一个网站打开另一个选项卡,并使该选项卡与我的脚本在后台运行 30 秒,然后返回到代码选项卡,您将看到所有段落现在都带有没有协调或同步。

非常感谢!

I developed a little script that make texts like they were coming from far, with jQuery and animate() function.
I have 2 main problem. The first is described here:
Jquery font size animation problem in Chrome, too laggy

The second is that I need to loop the animation. The way I did works well, but in FireFox it has been implemented a resource saving mechanism that makes things weird when the tab windows of the broser is in background.

I'm quite sure the problem is known, and concern what you can read on Jquery doc for animate():

Because of the nature of requestAnimationFrame(), you should never queue animations using a setInterval or setTimeout loop. In order to preserve CPU resources, browsers that support requestAnimationFrame will not update animations when the window/tab is not displayed. If you continue to queue animations via setInterval or setTimeout while animation is paused, all of the queued animations will begin playing when the window/tab regains focus. To avoid this potential problem, use the callback of your last animation in the loop, or append a function to the elements .queue() to set the timeout to start the next animation.

...but I cannot understand how to apply a solution to my script.

You can test and play with the code here: http://jsbin.com/ehahoc/7/

Just open the code on a tab, then open another tab from another website and keep the tab with my script running in the background for 30 sec, then come back to the code tab and you will see that all the paragraph are now coming with no coordination or sync.

Many thanks!

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

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

发布评论

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

评论(1

短暂陪伴 2024-12-12 02:28:18

我遇到了完全相同的问题。不好的事情是你将 setInterval/setTimeout 与 jQuery 的 .animate() 函数一起使用。

jQuery 文档说(来源):

由于 requestAnimationFrame() 的性质,您永远不应该使用 setInterval 或 setTimeout 循环对动画进行排队。为了节省CPU资源,支持requestAnimationFrame的浏览器在窗口/选项卡未显示时不会更新动画。如果在动画暂停时继续通过 setInterval 或 setTimeout 对动画进行排队,则当窗口/选项卡重新获得焦点时,所有排队的动画将开始播放。为了避免这种潜在的问题,请使用循环中最后一个动画的回调,或者将一个函数附加到 elements.queue() 来设置启动下一个动画的超时。

乍一看,这听起来比实际上更困难。问题是 jQuery 向队列中添加了越来越多的动画,但是支持 requestAnimationFrame 的现代浏览器在您重新激活选项卡之前不会执行这些动画。您可以使用(或者在您的情况下仅检查)元素的 .queue() 来解决此问题。要了解 .queue(),已经有一篇关于该问题的文章

一个简单的解决方案可能是将 ChangeText() 函数的内容包装在以下条件中 - 在向其中添加新动画之前检查“fx”队列是否为空:

var $activeText = $(".container .active-text");

if( $activeText.queue('fx').length == 0 ) {
    // do funky animations, but only if the queue is empty...
}

这应该可以解决这种情况下的问题。您可以在此处找到修复示例的克隆版本。

I ran into the exact same problem. The bad thing is that you use setInterval/setTimeout together with jQuery's .animate() function.

The jQuery documentation says (source):

Because of the nature of requestAnimationFrame(), you should never queue animations using a setInterval or setTimeout loop. In order to preserve CPU resources, browsers that support requestAnimationFrame will not update animations when the window/tab is not displayed. If you continue to queue animations via setInterval or setTimeout while animation is paused, all of the queued animations will begin playing when the window/tab regains focus. To avoid this potential problem, use the callback of your last animation in the loop, or append a function to the elements .queue() to set the timeout to start the next animation.

At the first glance this sounds more difficult than it actually is. The problem is that jQuery adds more and more animations to the queue, but modern browsers that support requestAnimationFrame do not execute these animations until you re-activate the tab. You can solve this using (or in your case just checking) the .queue() of the element. To understand the .queue(), there's already an article about that.

A simple solution could be to wrap the content of your changeText() function in the following condition - checking the "fx" queue to be empty before adding new animations to it:

var $activeText = $(".container .active-text");

if( $activeText.queue('fx').length == 0 ) {
    // do funky animations, but only if the queue is empty...
}

This should fix the problem in this case. You can find a cloned version of your fixed example here.

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