javascript - 当 Chrome 中的选项卡处于非事件状态时,如何使 setInterval 也起作用?

标签 javascript google-chrome setinterval

我有一个 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/5927284/

相关文章:

javascript - Firefox 中的渲染顺序

html - 列表元素不适合 IE 和 MAC 的 Chrome 上的给定空间

css - 必须删除 Chrome 中的缓存才能查看我在 Wordpress 网站上所做的 css 更改。这可以自动处理吗?

php - 是什么导致 chrome 出现 "unexpectedly closed the connection ERR_INCOMPLETE_CHUNKED_ENCODING"

javascript - jQuery for 循环问题的 setInterval

javascript - 有没有办法让浏览器中的时间快进来触发页面上设置的setTimeouts?

javascript - Mighty Signal 这个动画背景是怎么做的?

javascript - python 的 Maps api 几何库

javascript - 数组上的setInterval

使用 setInterval 调用的方法将 Javascript 对象属性报告为未定义