Javascript requestAnimationFrame在被函数调用之前正在运行

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

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

我当前的代码:


时间:
点击我
const button=document.getElementById('button');
按钮。addEventListener('单击',单击按钮);
函数clickButton(){
运行计时器();
}
函数runTimer(){
让rAF_识别;
设rAFCallback=函数(回调){
让计数=回调;
设s=Math.floor((count/1000)%60).toString().padStart(2,'0');
设m=数学地板((计数/60000)%60);
document.getElementById('labelTime')。innerHTML=m+“:”+s;
rAF_ID=requestAnimationFrame(rAFCallback);
}
rAF_ID=requestAnimationFrame(rAFCallback);
}

传递到
rAFCallback
函数的
时间戳(
DOMHighResTimeStamp
)值不会从动画首次运行时开始,而是具有随上下文变化的“时间原点”

  • 如果脚本的全局对象是
    窗口
    ,则时间原点确定如下:

    • 如果当前
      文档
      是在
      窗口
      中加载的第一个文档,则时间原点是创建浏览器上下文的时间
    • 如果在卸载窗口中加载的上一个文档的过程中,显示了一个确认对话框,允许用户确认是否离开上一页,则时间原点是用户确认导航到新页是可接受的时间
    • 如果上述两项均未确定时间原点,则时间原点是负责创建窗口当前文档的导航发生的时间
  • 如果脚本的全局对象是WorkerGlobalScope(即,脚本作为web工作程序运行),则时间原点是创建工作程序的时刻
  • 在所有其他情况下,时间原点未定义
因此,如果希望从动画开始时获取增量时间值,则需要自己执行,如下所示:

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

动画函数的参数应命名为
时间戳
(或类似名称),而不是
回调
,因为它不是
函数
值。