我有一个setInterval,每秒运行一段代码30次。这工作得很好,但是当我选择另一个选项卡(使我的代码选项卡变得不活跃),setInterval由于某种原因被设置为空闲状态。
我制作了这个简化的测试用例(http://jsfiddle.net/7f6DX/3/):
var $div = $('div');
var a = 0;
setInterval(function() {
a++;
$div.css("left", a)
}, 1000 / 30);
如果您运行这段代码,然后切换到另一个选项卡,等待几秒钟并返回,动画将继续在切换到另一个选项卡时的位置。
因此,如果标签处于非活动状态,动画不会每秒运行30次。这可以通过计算每秒调用setInterval函数的次数来确认——如果选项卡处于非活动状态,这将不是30,而是1或2。
我想这样做是为了提高系统性能,但是有什么方法可以禁用这种行为吗?
这在我看来是劣势。
只要这样做:
var $div = $('div');
var a = 0;
setInterval(function() {
a++;
$div.stop(true,true).css("left", a);
}, 1000 / 30);
不活跃的浏览器选项卡缓冲了一些setInterval或setTimeout函数。
Stop (true,true)将停止所有缓冲事件,并立即只执行最后一个动画。
window.setTimeout()方法现在限制在非活动选项卡中每秒发送不超过一个超时。此外,它现在将嵌套超时限制到HTML5规范允许的最小值:4毫秒(而不是以前的10毫秒)。
我为那些试图在计时器函数中解决这个问题的人带来了一个简单的解决方案,正如@kbtzr在另一个答案中提到的那样,我们可以使用Date对象而不是固定增量来计算自开始以来经过的时间,即使您离开了应用程序的选项卡,这也可以工作。
这是HTML示例。
<body>
<p id="time"></p>
</body>
然后这个JavaScript:
let display = document.querySelector('#time')
let interval
let time
function startTimer() {
let initialTime = new Date().getTime()
interval = setInterval(() => {
let now = new Date().getTime()
time = (now - initialTime) + 10
display.innerText = `${Math.floor((time / (60 * 1000)) % 60)}:${Math.floor((time / 1000) % 60)}:${Math.floor((time / 10) % 100)}`
}, 10)
}
startTimer()
这样,即使由于非活动选项卡的性能原因而增加了间隔值,所做的计算也将保证正确的时间。这是一个普通的代码,但我在我的React应用程序中使用了这种逻辑,你也可以在任何你需要的地方修改它。
这是一个很老的问题,但我遇到了同样的问题。
如果你在chrome上运行你的网页,你可以阅读这篇文章在chrome 57的背景标签。
基本上间隔计时器可以运行,如果它没有耗尽定时器预算。
预算的消耗基于计时器内任务的CPU时间使用情况。
基于我的场景,我将视频绘制到画布上并传输到WebRTC。
webrtc视频连接将保持更新,即使标签是不活跃的。
然而,你必须使用setInterval而不是requestAnimationFrame,但是itt不推荐用于UI渲染。
最好是监听visibilityChange事件并相应地改变渲染机制。
此外,您可以尝试Kaan Soral建议的方法,它应该可以根据文档工作。