查看vant代码发现,用的是requestAnimationFrame方法实现。
requestAnimationFrame
window.requestAnimationFrame()方法会告诉浏览器你希望执行一个动画。它要求浏览器在下一次重绘之前,调用用户提供的回调函数。对回调函数的调用频率通常与显示器的刷新率相匹配。虽然 75hz、120hz 和 144hz 也被广泛使用,但是最常见的刷新率还是 60hz(每秒 60 个周期/帧)。为了提高性能和电池寿命,大多数浏览器都会暂停在后台选项卡或者隐藏的
<iframe>中运行的requestAnimationFrame()。
我的理解是requestAnimationFrame通过浏览器的刷新帧数进行回调函数的调用,所以回调函数中对动画的执行度会比定时器实现得更为流畅。
另外,当使用了requestAnimationFrame方法后,可通过cancelAnimationFrame取消。
计时器简单实现
const SECOND = 1000;
const MINUTE = 60 * SECOND;
const HOUR = 60 * MINUTE;
const DAY = 24 * HOUR;
// 当数值小于10时在前面补0
function timeTextFormat(num) {
return num < 10 ? '0' + num : num;
}
// 根据时间戳得出天-时-分-秒
function parseTime(timestamp) {
const DD = Math.floor(timestamp / DAY);
const hh = Math.floor((timestamp % DAY) / HOUR);
const mm = Math.floor((timestamp % HOUR) / MINUTE);
const ss = Math.floor((timestamp % MINUTE) / SECOND);
// console.log(`${DD} ${hh}:${mm}:${ss}`)
textEle.innerHTML = `${DD} ${timeTextFormat(hh)}:${timeTextFormat(mm)}:${timeTextFormat(ss)}`;
}
const endTime = new Date('2025/05/21 17:58:00').getTime();
// 取消的id
let reqId;
// 倒计时操作
function start() {
const currentTime = new Date().getTime();
const agio = endTime - currentTime;
// 当前之间和指定时间的时间差小于0时,取消执行
if (agio <= 0) {
console.log('取消')
return cancelAnimationFrame(reqId)
}
parseTime(agio);
reqId = requestAnimationFrame(start);
}
start()