我有一个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。
我想这样做是为了提高系统性能,但是有什么方法可以禁用这种行为吗?
这在我看来是劣势。
这是一个很老的问题,但我遇到了同样的问题。
如果你在chrome上运行你的网页,你可以阅读这篇文章在chrome 57的背景标签。
基本上间隔计时器可以运行,如果它没有耗尽定时器预算。
预算的消耗基于计时器内任务的CPU时间使用情况。
基于我的场景,我将视频绘制到画布上并传输到WebRTC。
webrtc视频连接将保持更新,即使标签是不活跃的。
然而,你必须使用setInterval而不是requestAnimationFrame,但是itt不推荐用于UI渲染。
最好是监听visibilityChange事件并相应地改变渲染机制。
此外,您可以尝试Kaan Soral建议的方法,它应该可以根据文档工作。
我在使用HTML5播放器时也遇到了同样的问题。当标签变成非活动时,它被卡住了。
所以我发现WebWorker允许使用没有限制的间隔/超时。我用它来张贴“tick”到主javascript。
WebWorkers代码:
var fading = false;
var interval;
self.addEventListener('message', function(e){
switch (e.data) {
case 'start':
if (!fading){
fading = true;
interval = setInterval(function(){
self.postMessage('tick');
}, 50);
}
break;
case 'stop':
clearInterval(interval);
fading = false;
break;
};
}, false);
主要Javascript:
var player = new Audio();
player.fader = new Worker('js/fader.js');
player.faderPosition = 0.0;
player.faderTargetVolume = 1.0;
player.faderCallback = function(){};
player.fadeTo = function(volume, func){
console.log('fadeTo called');
if (func) this.faderCallback = func;
this.faderTargetVolume = volume;
this.fader.postMessage('start');
}
player.fader.addEventListener('message', function(e){
console.log('fader tick');
if (player.faderTargetVolume > player.volume){
player.faderPosition -= 0.02;
} else {
player.faderPosition += 0.02;
}
var newVolume = Math.pow(player.faderPosition - 1, 2);
if (newVolume > 0.999){
player.volume = newVolume = 1.0;
player.fader.postMessage('stop');
player.faderCallback();
} else if (newVolume < 0.001) {
player.volume = newVolume = 0.0;
player.fader.postMessage('stop');
player.faderCallback();
} else {
player.volume = newVolume;
}
});