如果选项卡失去焦点,则在FireFox中使用setInterval循环的jQuery动画问题

时间:2011-09-15 16:22:54

标签: jquery firefox tabs jquery-animate setinterval

我开发了一个小脚本,使用jQuery和animate()函数创建类似于它们的文本。 我有两个主要问题。第一个描述如下: Jquery font size animation problem in Chrome, too laggy

第二是我需要循环播放动画。我的方式运作良好,但在FireFox中,它实现了一种资源节约机制,当浏览器的选项卡窗口处于后台时会使事情变得怪异。

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

  

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

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

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

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

非常感谢!

1 个答案:

答案 0 :(得分:1)

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

jQuery文档说(source):

  

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

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

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

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

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

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