Javascript setInterval 在选项卡未激活时无法正常工作

Javascript setInterval doesn't work correctly when tab is not active

本文关键字:常工作 工作 setInterval 选项 激活 Javascript      更新时间:2023-09-26
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,即使选项卡未处于活动状态,它也能正常工作

使用 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>

请注意,通过更频繁地检查它,我们可以确保它永远不会偏离太多。

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);
    }