当 Chrome 中的选项卡处于非活动状态时,如何使 setInterval 也能工作? [英] How can I make setInterval also work when a tab is inactive in Chrome?

查看:54
本文介绍了当 Chrome 中的选项卡处于非活动状态时,如何使 setInterval 也能工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 setInterval 每秒运行一段代码 30 次.这很好用,但是当我选择另一个选项卡时(这样带有我的代码的选项卡变为非活动状态),setInterval 由于某种原因被设置为空闲状态.

I have a setInterval running a piece of code 30 times a second. This works great, however when I select another tab (so that the tab with my code becomes inactive), the setInterval is set to an idle state for some reason.

我做了这个简化的测试用例(http://jsfiddle.net/7f6DX/3/):

I made this simplified test case (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.

If you run this code and then switch to another tab, wait a few seconds and go back, the animation continues at the point it was when you switched to the other tab. So the animation isn't running 30 times a second in case the tab is inactive. This can be confirmed by counting the amount of times the setInterval function is called each second - this will not be 30 but just 1 or 2 if the tab is inactive.

我猜这是为了提高性能而设计的,但是有没有办法禁用这种行为?在我的情况下,这实际上是一个劣势.

I guess that this is done by design so as to improve performance, but is there any way to disable this behaviour? It is actually a disadvantage in my scenario.

推荐答案

在大多数浏览器上,非活动选项卡的执行优先级较低,这会影响 JavaScript 计时器.

On most browsers inactive tabs have low priority execution and this can affect JavaScript timers.

如果您的过渡值是使用帧之间经过的实时时间而不是每个间隔的固定增量来计算的,那么您不仅可以解决此问题,还可以通过使用 requestAnimationFrame 因为它可以达到 60fps如果处理器不是很忙.

If the values of your transition were calculated using real time elapsed between frames instead fixed increments on each interval, you not only workaround this issue but also can achieve a smother animation by using requestAnimationFrame as it can get up to 60fps if the processor isn't very busy.

这是一个使用 requestAnimationFrame 的动画属性转换的普通 JavaScript 示例:

Here's a vanilla JavaScript example of an animated property transition using requestAnimationFrame:

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>

@UpTheCreek 评论:

@UpTheCreek comment:

对于演示问题很好,但仍然有些事情你需要继续运行.

Fine for presentation issues, but still there are some things that you need to keep running.

如果您有需要在给定时间间隔内精确执行的后台任务,您可以使用 HTML5 Web Workers.看看 Möhre 的回答如下 了解更多详情...

If you have background tasks that needs to be precisely executed at given intervals, you can use HTML5 Web Workers. Take a look at Möhre's answer below for more details...

这个问题和许多其他问题可以通过使用 CSS 来避免转换/动画而不是基于 JavaScript 的动画,这增加了相当大的开销.我推荐这个 jQuery 插件,让您从 CSS 转换中受益就像 animate() 方法一样.

This problem and many others could be avoided by using CSS transitions/animations instead of JavaScript based animations which adds a considerable overhead. I'd recommend this jQuery plugin that let's you take benefit from CSS transitions just like the animate() methods.

这篇关于当 Chrome 中的选项卡处于非活动状态时,如何使 setInterval 也能工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆