function initTimer(timeLeft) {
var Me = this,
TotalSeconds = 35,
Seconds = Math.floor(timeLeft);
var x = window.setInterval(function() {
var timer = Seconds;
if(timer === -1) { clearInterval(x); return; }
$('#div').html('00:' + (timer < 10 ? '0' + timer : timer));
Seconds--;
},1000);
}
我有这个代码。一切正常,当此选项卡在浏览器中处于活动状态时,但是当我更改选项卡并稍后在选项卡中返回时,它会出现问题。更准确地说,它错误地显示时间。
我也试过了setTimeout,但问题是一样的。
我的一个想法是:HTML5 Web Workers ......
但这是另一个问题......浏览器支持。
有人可以帮助解决这个问题吗? 如何编写setInterval,即使tab不活动也能正常工作
答案 0 :(得分:2)
使用Date
对象计算时间。当你问它时,不要依赖计时器触发(它们不是实时的),因为你唯一的保证就是在你要求它之前不会发射。它可能会在很晚的时候激活,尤其是对于非活动选项卡。尝试这样的事情:
function initTimer(periodInSeconds) {
var end = Date.now() + periodInSeconds * 1000;
var x = window.setInterval(function() {
var timeLeft = Math.floor((end - Date.now()) / 1000);
if(timeLeft < 0) { clearInterval(x); return; }
$('#div').html('00:' + (timeLeft < 10 ? '0' + timeLeft : timeLeft));
},200);
}
initTimer(10);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="div"></div>
请注意,通过更频繁地检查它,我们可以确保它永远不会过多。
答案 1 :(得分:1)
即使标签处于有效状态,JavaScript定时器也不可靠。他们只保证至少你指定的时间已经过去了;无法保证完全那段时间,甚至是接近它的任何时间都已过去。
要解决此问题,每当间隔触发时,请注意它的时间。您实际上只需要跟踪两次:当前时间和上一个间隔触发的时间。通过从当前刻度的时间减去前一个刻度的时间,您可以知道实际在两者之间传递了多少时间,并相应地运行计算。
以下是这样的事情的基本概要:
function initTimer(timeLeft) {
var Me = this,
TotalSeconds = 35,
Seconds = Math.floor(timeLeft),
CurrentTime = Date.now(),
PreviousTime = null;
var x = window.setInterval(function() {
var timer = Seconds,
timePassed;
PreviousTime = CurrentTime;
CurrentTime = Date.now();
timePassed = CurrentTime - PreviousTime;
if(timer < 0) { clearInterval(x); return; }
$('#div').html('00:' + (timer < 10 ? '0' + timer : timer));
Seconds = Seconds - timePassed;
},1000);
}