我有一个 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。
我猜这是设计使然,以便提高系统性能,但是有什么办法可以禁用这种行为吗?
在我的场景中这实际上是一个缺点。
最佳答案
在大多数浏览器上,非事件选项卡的执行优先级较低,这可能会影响 JavaScript 计时器。
如果使用帧之间经过的实时时间而不是每个间隔的固定增量来计算过渡值,您不仅可以解决此问题,还可以通过使用 requestAnimationFrame 实现更平滑的动画因为如果处理器不是很忙的话它可以达到 60fps。
这是一个使用 requestAnimationFrame
进行动画属性转换的普通 JavaScript 示例:
var target = document.querySelector('div#target')
var startedAt, duration = 3000
var domain = [-100, window.innerWidth]
var range = domain[1] - domain[0]
function start() {
startedAt = Date.now()
updateTarget(0)
requestAnimationFrame(update)
}
function update() {
let elapsedTime = Date.now() - startedAt
// playback is a value between 0 and 1
// being 0 the start of the animation and 1 its end
let playback = elapsedTime / duration
updateTarget(playback)
if (playback > 0 && playback < 1) {
// Queue the next frame
requestAnimationFrame(update)
} else {
// Wait for a while and restart the animation
setTimeout(start, duration/10)
}
}
function updateTarget(playback) {
// Uncomment the line below to reverse the animation
// playback = 1 - playback
// Update the target properties based on the playback position
let position = domain[0] + (playback * range)
target.style.left = position + 'px'
target.style.top = position + 'px'
target.style.transform = 'scale(' + playback * 3 + ')'
}
start()
body {
overflow: hidden;
}
div {
position: absolute;
white-space: nowrap;
}
<div id="target">...HERE WE GO</div>
对于后台任务(与 UI 无关)
@UpTheCreek 评论:
Fine for presentation issues, but still there are some things that you need to keep running.
如果您有需要在给定时间间隔精确执行的后台任务,您可以使用 HTML5 Web Workers 。看看Möhre's answer below了解更多详情...
CSS 与 JS“动画”
这个问题和many others可以通过使用 CSS 过渡/动画而不是基于 JavaScript 的动画来避免,这会增加相当大的开销。我推荐这个jQuery plugin这让您可以像 animate()
方法一样受益于 CSS 转换。
关于javascript - 当 Chrome 中的选项卡处于非事件状态时,如何使 setInterval 也起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34128241/