javascript - requestAnimationFrame 在被函数调用之前运行

标签 javascript

我正在尝试使用 JavaScript 和 requestAnimationFrame 制作一个简单的计时器(从 0 开始计数)。我想在点击某物时从 0 开始计时器。目前,我的代码在单击按钮时显示计时器,但在我看来, requestAnimationFrame 甚至在调用该函数之前就已运行。如果您在网页上加载代码并等待几秒钟,然后单击按钮,您将看到计时器不是从 0 开始,而是从页面首次加载以来的秒数开始。我不知所措,谷歌搜索并没有帮助我弄清楚为什么/如何在调用函数之前计时器开始计数。

我当前的代码:

<div class="time">
  Time: <label id="labelTime"></label>
</div>
<button id="button">Click me</button>
<script>
  const button = document.getElementById('button');
  button.addEventListener('click', clickButton);

  function clickButton() {
    runTimer();
  }

  function runTimer() {
    let rAF_ID;

    let rAFCallback = function(callback) {
      let count = callback;

      let s = Math.floor((count / 1000) % 60).toString().padStart(2, '0');
      let m = Math.floor((count / 60000) % 60);

      document.getElementById('labelTime').innerHTML = m + ":" + s;
      rAF_ID = requestAnimationFrame(rAFCallback);
    }
    rAF_ID = requestAnimationFrame(rAFCallback);
  }
</script>

最佳答案

传递给 rAFCallback 函数的 timestamp (DOMHighResTimeStamp) 值并非从动画首次运行时开始,而是有一个“时间起源”根据上下文而变化。

https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp

  • If the script's global object is a Window, the time origin is determined as follows:

    • If the current Document is the first one loaded in the Window, the time origin is the time at which the browser context was created.
    • If during the process of unloading the previous document which was loaded in the window, a confirmation dialog was displayed to let the user confirm whether or not to leave the previous page, the time origin is the time at which the user confirmed that navigating to the new page was acceptable.
    • If neither of the above determines the time origin, then the time origin is the time at which the navigation responsible for creating the window's current Document took place.
  • If the script's global object is a WorkerGlobalScope (that is, the script is running as a web worker), the time origin is the moment at which the worker was created.
  • In all other cases, the time origin is undefined.

因此,如果您想获取动画开始时的增量时间值,您需要自己执行此操作,如下所示:

let timestampAtStart = null;
let lastRequestId    = null;

function myAnimateFunction( timestamp ) {
    if( !timestampAtStart ) {
        timestampAtStart = timestamp;
    }

    let timeSinceStart = timestamp - timestampAtStart;

    console.log( timeSinceStart );

    lastRequestId = window.requestAnimationFrame( myAnimateFunction );
}

function startAnimation() {

    if( lastRequestId ) window.cancelAnimationFrame( lastRequestId );

    timestampAtStart = null;

    lastRequestId = window.requestAnimationFrame( myAnimateFunction );
}

关于javascript - requestAnimationFrame 在被函数调用之前运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56095782/

相关文章:

javascript - 使用 node.js 将重复的 HTML 片段导入到其他 html 文件中

javascript - 不明白为什么 Canvas 没有被编辑

javascript - 有没有一种简单的方法可以将 "font"样式属性转换为每个单独的样式?

javascript - React Router 中的 match.url 到底是什么?

javascript - Raphael 不透明度在 IE 上不显示

javascript - 使用多个类更改字体

javascript - jQuery UI 可排序 'out' 未与多个连接的可排序一起触发

javascript - 如何在 Nuxt.js 的服务器端使用 css 中的 v-bind

javascript - WordPress 的 video.js : JavaScript error in IE 8

javascript - 如何使用javascript将字符串解析为单词和标点符号