我最近创建了一个 HTML5 画布动画(也使用 Processing.js)。
问题是当我将浏览器切换到不同的选项卡时,动画会停止播放。
当用户在与包含动画的选项卡不同的选项卡上时,如何允许动画继续播放?
示例:http: //jsfiddle.net/EyFTr/3/
如果您切换标签,时钟会停止,但如果您打开一个新窗口链接并模糊窗口,时钟仍然会移动。
我最近创建了一个 HTML5 画布动画(也使用 Processing.js)。
问题是当我将浏览器切换到不同的选项卡时,动画会停止播放。
当用户在与包含动画的选项卡不同的选项卡上时,如何允许动画继续播放?
示例:http: //jsfiddle.net/EyFTr/3/
如果您切换标签,时钟会停止,但如果您打开一个新窗口链接并模糊窗口,时钟仍然会移动。
简短的回答是你不能。
https://developer.mozilla.org/en/DOM/window.setTimeout
在(Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2)和 Chrome 11 中,超时被限制为在非活动选项卡中每秒触发一次(1000 毫秒);请参阅错误 633421 了解 Mozilla 中的更多信息,或 crbug.com/66078 了解 Chrome 中的详细信息。
有问题的浏览器在该引用中有点旧,但仍然相关。这是设计使然。当标签未激活时,它会减少处理器负载。(Processing.jssetTimeout
用于动画)
有几种方法可以“解决”这个问题。它们涉及检查时间,并在选项卡激活后根据时间计算对象“应该”在哪里。然而,在您的示例中,尽管您的代码看起来会这样做,因为它是一个无论如何都基于时间的时钟。
正如 Loktar 所建议的,这种症状可以通过检查时间并弄清楚你应该在哪里来缓解。这是一个可以做到这一点的函数:
function smartInterval(func, interval){
var last = new Date() - interval,
now,
numMissed;
(function iterate(){
func();
// compute the number of iterations you might have missed
// if you tabbed away and the interval was restricted to 1000ms
now = +new Date();
numMissed = Math.round((now - last) / interval) - 1;
// make up for those iterations that were lost
while (numMissed--) { func(); }
last = +new Date();
setTimeout(iterate, interval);
})();
}
用法:
smartInterval(function(){console.log('hi');}, 100);
这是一个带有示例的 jsFiddle。尝试注释掉while
循环 ( while (numMissed--)
) 以查看通过切换到选项卡,您会得到更少的数字。然而,有了while
循环,间隔似乎从未改变过。
不幸的是,这可能对您没有任何用处,因为您使用的是 Processing.js 并且超时是在内部设置的。
请参阅setInterval 在 Chrome 上无法正常工作。本质上,浏览器会在后台处理 setInterval 以提高性能,因此您无法准确控制发生的情况。