有一个计时秒和毫秒的计时器

Have A Timer That Counts both Seconds and Milliseconds

大家好我有什么应该是一个简单的问题。基本上我需要一个计时器来计算秒数和毫秒数。我已经构建了一个以秒为单位倒计时的计时器,但是 运行 在添加毫秒功能时遇到了一些麻烦。当我尝试添加第二个计时器并将其简单地放在第一个计时器旁边时,它干扰了我的第一个计时器。我 Java 编写脚本的时间不长,所以我不知道下一步该做什么。

<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>

    <body id="body">

        <div id="timer" style="font-family:helvetica; font-size:100px; text-align:center;">24 secs</div>
        <script>
            var count = 24,
                counter = setInterval(timer, 1000),
                running = true;

            function timer() {
                count -= 1;
                if (count <= 0) {
                    clearInterval(counter);
                }
                document.getElementById("timer").innerHTML = count + " secs";
            }
            window.addEventListener("keydown", function(e) {
                switch (e.keyCode) {
                    case 32: // PLAY
                        running ? clearInterval(counter) : counter = setInterval(timer, 1000);
                        running = !running;
                        break;
                    case 82: // RESET
                        clearInterval(counter);
                        document.getElementById("timer").innerHTML = 24 + " secs";
                        count = 24;
                        running = false;
                }
            });
        </script>
    </body>

</html>  

将您的代码更改为此以显示当前秒的毫秒值。我没有对其进行广泛测试,因此您必须进行一些修改。这是一个 10 毫秒的间隔。

var count = 24,
    intervalMs = 10,
    counter = setInterval(timer, intervalMs),
    running = true,
    msRemaining = 1000;

function timer() {
    msRemaining -= intervalMs;
    if (msRemaining <= 0)
    {
        count -= 1;
        if (count <= 0) {
            clearInterval(counter);
        }
        msRemaining = 1000;
    }

    document.getElementById("timer").innerHTML = count + " secs," + msRemaining + " ms";
}

这个问题比乍看之下稍微不那么琐碎。

您无法真正地 毫秒显示一次,因为浏览器无法处理它。

如果对旧浏览器(比如 2012 年之前)的支持不是问题,我会使用这样的东西:

var count = 24000,
  running = true,
  secondsNode = document.getElementById("seconds"),
  millisecondsNode = document.getElementById("milliseconds"),
  mOld,
  mNew;

function draw() {
  if (count > 0 && running) {
    requestAnimationFrame(draw);
    mNew = new Date().getTime();
    count = count - mNew + mOld;
    count = count >= 0 ? count : 0;
    mOld = mNew;
    secondsNode.innerHTML = Math.floor(count / 1000);
    millisecondsNode.innerHTML = count % 1000;
  }
}
mOld = new Date().getTime();
draw();

window.addEventListener("keydown", function(e) {
  switch (e.keyCode) {
    case 32: // PLAY
      if (running) {
        running = false;
      } else {
        running = true;
        mOld = new Date().getTime();
        draw();
      }
      break;
    case 82: // RESET
      count = 24000;
      secondsNode.innerHTML = 24;
      millisecondsNode.innerHTML = 0;
      running = false;
  }
});
p {
  font-family: helvetica;
  font-size: 100px;
  text-align: center;
}
<body id="body">

  <p><span id="seconds">24</span> secs and <span id="milliseconds">000</span> milliseconds</p>

</body>

这里的核心是方法requestAnimationFrame(...);。简单地说,它是一种原生 JS 方法,一旦浏览器准备好 "draw" 一个新框架,它就会执行作为 parameter 提供的 function

因为我们不知道自上次执行以来已经过了多少时间,我们需要使用 current datetime 相对于 datetime我们的方法 上次执行.


旁注:

经常需要的 nodes 应该保存到 variable 而不是每次需要时都保存在 "calculated" 中。 (secondsNode = document.getElementById(...) 节省资源,因为文档只需要traversed 一次。)

Here some further reading on requestAnimationFrame.

And the above code as a Fiddle.