当前位置: 首页 > 知识库问答 >
问题:

倒数计时器落后了

吴高畅
2023-03-14

我正在尝试在两个日期之间创建倒计时,但时间过了一段时间就落后了。

我的PHP后端返回当前时间和未来X时间之间的差值,例如当前时间和提前2小时。这个差异在中传递给我的HTML frontent。倒计时类,格式如下03:20:15,我使用javascript函数对差异进行倒计时。以下是我的功能:

$(".countdown").each(function() {
   var $e = $(this);
   var interval = setInterval(function() { 
      var timer2 = $e.html();
      var timer = timer2.split(':');
      var hours = parseInt(timer[0], 10);
      var minutes = parseInt(timer[1], 10);
      var seconds = parseInt(timer[2], 10);
      --seconds;
      minutes = (seconds < 0) ? --minutes : minutes;
      hours = (minutes < 0) ? --hours : hours;
      if(hours < 0) {
         clearInterval(interval);
         window.location.reload();
      } else {
         seconds = (seconds < 0) ? 59 : seconds;
         seconds = (seconds < 10) ? '0' + seconds : seconds;
         minutes = (minutes < 0) ? 59 : minutes;
         minutes = (minutes < 10) ? '0' + minutes : minutes;
         hours = (hours < 10) ? '0' + hours : hours;
         $e.html(hours + ':' + minutes + ':' + seconds);
      }
   }, 1000);
});

代码按预期工作,但几分钟后,比方说2-3分钟,如果您刷新页面或在新窗口中打开它,您将看到倒计时计时器落后秒/分钟。有人知道我做错了什么吗?

共有1个答案

韩宏朗
2023-03-14

您应该计算(new Date())和目标日期之间的差异。使用这种差异并格式化新的超文本标记语言字符串,而不是将其解析为递减的小时、分钟、秒值。

细节

setInterval api规范表明,CPU负载、其他任务等导致的延迟是可以预料的。https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers

当您认为它们是精确的时,您的处理程序以大约相等的间隔被调用。在第一次迭代时,实际时间可能与计划时间相差很小(比方说4ms)。然而,你改变你的计数器1000毫秒。随着更多的迭代通过,这种差异会积累并变得明显。几分钟足以让这一切发生。

另一方面,如果您预先计算目标日期时间值,并使用当前时间和目标时间之间的差值,那么您的代码将无法感知api的不精确性。

$(".countdown").each(function () {
    var $e = $(this);

    const totalSeconds = (dt) => Math.floor(dt.valueOf() / 1000);

    const f1 = (timer2) => {
        var timer = timer2.split(':');
        var tdt = new Date().setHours(
            parseInt(timer[0]) + tdt.getHours(),
            parseInt(timer[1]) + tdt.getMinutes(),
            parseInt(timer[2]) + tdt.getSeconds());
        return totalSeconds(tdt);
    };

    const targetTime = f1($e.html());

    setInterval(function () {
        var timeSpan = targetTime - totalSeconds(new Date());

        if (timeSpan < 0) {
            window.location.reload();
        } else {
            var seconds = timeSpan % 60;
            var totalMinutes = Math.floor(timeSpan / 60);
            var minutes = totalMinutes % 60;
            var hours = Math.floor(totalMinutes / 60);

            $e.html(hours + ':' + minutes + ':' + seconds);;
        }
    }, 1000);
});

另见:https://jsfiddle.net/8dygbo9a/1/

 类似资料:
  • 问题内容: 我已经在JavaScript中看到了许多倒数计时器,并希望在React中使用它。 我借用了我在网上找到的此功能: 然后我自己写了这段代码 当前onclick会将其在屏幕上的时间设置为: 但不会将其减少到,然后等等等 我想我需要使用其他参数再次调用该函数。我该怎么做呢? 编辑:我忘了说,我想要功能,这样我就可以使用秒到分钟和秒 问题答案: 您必须每秒剩余几秒钟(每次调用间隔)。这是一个例

  • 本文向大家介绍JAVA CountDownLatch(倒计时计数器)用法实例,包括了JAVA CountDownLatch(倒计时计数器)用法实例的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了JAVA CountDownLatch(倒计时计数器)用法实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 方法说明: public voi

  • 本文向大家介绍Android倒计时神器(CountDownTimer),包括了Android倒计时神器(CountDownTimer)的使用技巧和注意事项,需要的朋友参考一下 Android倒计时神器 - CountDownTimer,供大家参考,具体内容如下 啥是CountDownTimer?​ CountDownTimer是Andorid.os包下一个谷歌为我们封装好的一个倒计时工具。我们吗、

  • 问题内容: 我创建了一个计时器,该计时器在按下按钮时启动,上面是运行的代码。谁能帮我创建一个计数为30的计时器?现在,当我运行它时,在标签中设置文本“ 30”,但我希望它从0开始并一直计数到30。 问题答案: 每次您的计时器运行时,它都会执行从0到30的循环,因此仅在循环结束时才刷新UI。您需要将i保留为成员,并在每次这样调用该方法时对其进行更新: 当然,一旦达到i = 30,您就应该取消时间,否

  • 问题内容: 只是想问问如何创建最简单的倒数计时器。 该网站上会有一句话: “注册将在05:00分钟后关闭!” 因此,我想做的是创建一个简单的js倒数计时器,该计时器从“ 05:00”到“ 00:00”,然后在结束时重置为“ 05:00”。 之前我一直在回答一些问题,但是对于我想做的事情,它们似乎都太过激烈了(日期对象等)。 问题答案: 我有两个演示,一个带演示,一个不带演示。两者都不使用日期函数,

  • 问题内容: 我正在创建一个需要ListView的应用程序,其中的元素数量不确定,每个元素都有一个从可变数量开始倒数的计时器。我能够成功地使 其中 之一倒计时,但是我不知道如何在ListView的每个元素中包括一个计时器。 我目前正在使用CountDownTimer(如果从网站复制,请确保将D大写,因为它们有误)。 任何向我指出正确方向的代码或资源都将受到赞赏。 这是我当前的EventAdapter