首页 > 解决方案 > JavaScript 倒计时计时器,按下按键即可重置计时器

问题描述

我试图弄清楚当我按下一个键时它如何从 30 倒数到 0,如果我再次按下该键它会做同样的事情,从 30 计数到 0(重置)。

有没有什么方法可以用 JavaScript 完成,而在 HTML 中只显示从 30 到 0 的数字而没有其他文本?

我尝试过使用其他示例,但是我认为我必须将脚本放在错误的位置。有人能给我举个例子,不仅是 JS,还有 HTML 标记应该是什么样子?将不胜感激。

我一直在尝试修改和使用的示例是:

<!DOCTYPE html>
<html>
<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
  <h2>JavaScript in Body</h2>
  <p id="demo"></p>

  <script>
    $(function() {

      var perc = 50 // User will be logged out after (minutes)
      var count = perc * 60;

      // RESET TIMER

      $(document).keypress(function() {
        var count = perc * 60; // PROBLEM
        alert('keypress works');
      });

      //COUNTDOWN

      var counter = setInterval(timer, 1000);

      function timer() {
        count = count - 1;
        if (count == -1) {
          // LOGOUT //
          return;
        }

        var seconds = count % 60;
        var minutes = Math.floor(count / 60);

        seconds %= 60;
        minutes %= 60;

        document.getElementById("seconds").innerHTML = seconds;
        document.getElementById("minutes").innerHTML = minutes;
        document.getElementById("start_time").innerHTML = inactive;
      };
    });
  </script>
</body>
</html>

标签: javascriptsetinterval

解决方案


这是使用 进行一秒倒计时的幼稚方法setInterval,它在至少n毫秒(1000 ms = 1s)过去后调用其参数函数。

/* an inaccurate counter */
let count;
let interval;
const timer = document.querySelector("#timer");

document.addEventListener("keydown", e => {
  if (e.code === "KeyX") {
    clearInterval(interval);
    count = 30;
    interval = setInterval(() => {
      timer.innerText = count--;

      if (count < 0) {
        clearInterval(interval);
      }
    }, 1000);
  }
});
<div id="timer">press "x" key</div>

这里的问题是提供给的 1000 毫秒setTimeout是调用之间的最小延迟。超过 1000 毫秒的延迟会累积并导致漂移。

如果精度很重要,请考虑使用日期/时间库。requestAnimationFrame还可以很方便地确保不会错过任何渲染,并且倒计时的更改(例如重置事件)可以快速反映到用户界面。

为了保持范围干净,我们可以使用闭包来初始化和运行计数器循环。此倒计时初始化程序可以返回一个函数来停止计数器,可由事件处理程序调用。

const runCountdown = (counter, el) => {
  let start = Date.now() / 1000;
  let running = true;

  (function tick() {
    const elapsed = Date.now() / 1000 - start;
    el.innerText = Math.max(0, counter - Math.floor(elapsed));

    if (running && elapsed < counter) {
      requestAnimationFrame(tick);
    }
  })();
  
  return () => (running = false);
};

let stop; 
document.addEventListener("keydown", e => {
  if (e.code === "KeyX") {
    stop?.();
    stop = runCountdown(30, document.querySelector("#count"));
  }
});
<p>Press the "x" key to start or restart the countdown.</p>
<div id="count"></div>


推荐阅读