javascript - requestAnimationFrame 在被函数调用之前运行
问题描述
我正在尝试使用 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>
解决方案
传递给你的函数的timestamp
( ) 值不是从动画第一次运行时开始的,而是它有一个“时间原点”,它因上下文而异。DOMHighResTimeStamp
rAFCallback
https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp
如果脚本的全局对象是 a
Window
,则时间原点确定如下:
- 如果当前
Document
是在 中加载的第一个Window
,则时间原点是创建浏览器上下文的时间。- 如果在卸载窗口中加载的上一个文档的过程中,显示一个确认对话框让用户确认是否离开上一个页面,时间原点是用户确认导航到新页面是可以接受的。
- 如果以上都不能确定时间原点,则时间原点是负责创建窗口当前文档的导航发生的时间。
- 如果脚本的全局对象是 WorkerGlobalScope(即脚本作为 web worker 运行),则时间原点是 worker 创建的时刻。
- 在所有其他情况下,时间原点是未定义的。
因此,如果您想从动画开始时获取增量时间值,您需要自己执行此操作,如下所示:
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 );
}
推荐阅读
- python - 在 ImageJ 中安装 python 脚本
- python - Python:如何在两个日期范围之间找到每个月的第一天
- python-3.x - Python Lex-Yacc 报告“检测到符号的无限递归”
- r - 如何在 z 方向剪辑线框图?
- python - Python:从 system32 或 SysWOW64 中删除文件夹的脚本
- java - 当有前导零时,整数会发生什么?
- amazon-web-services - AWS CloudFormation RDS 实例无法创建 - 找不到 DBCluster
- c# - 自定义控制器,不适用于区域
- python - 使用 Python Madlibs 自动化无聊的东西:替换匹配的正则表达式的麻烦(丢失标点符号)
- mysql - 将 mysql 密码保存在 bash 脚本中并使用它而不是 cmd 行