js实现倒计时
使用 setInterval 实现倒计时
通过 setInterval 定时器每秒更新剩余时间,适用于简单倒计时场景。
function countdown(seconds, callback) {
const timer = setInterval(() => {
seconds--;
callback(seconds);
if (seconds <= 0) clearInterval(timer);
}, 1000);
}
// 使用示例
countdown(10, (remaining) => {
console.log(`剩余时间: ${remaining}秒`);
});
使用 requestAnimationFrame 实现高精度倒计时
通过递归调用 requestAnimationFrame 实现更高精度的倒计时,适合需要平滑动画的场景。
function preciseCountdown(endTime, updateCallback, finishCallback) {
function update() {
const now = Date.now();
const remaining = Math.max(0, endTime - now);
updateCallback(Math.ceil(remaining / 1000));
if (remaining > 0) {
requestAnimationFrame(update);
} else {
finishCallback?.();
}
}
update();
}
// 使用示例
const targetTime = Date.now() + 10000; // 10秒后
preciseCountdown(
targetTime,
(sec) => console.log(`精确剩余: ${sec}秒`),
() => console.log('倒计时结束')
);
带暂停/继续功能的倒计时类
封装一个完整的倒计时类,支持暂停、继续和重置功能。
class Countdown {
constructor(duration, onUpdate, onComplete) {
this.duration = duration;
this.remaining = duration;
this.onUpdate = onUpdate;
this.onComplete = onComplete;
this.timer = null;
this.startTime = null;
}
start() {
this.startTime = Date.now();
this.timer = setInterval(() => {
this.remaining = Math.max(0, this.duration - Math.floor((Date.now() - this.startTime) / 1000));
this.onUpdate(this.remaining);
if (this.remaining <= 0) {
this.stop();
this.onComplete?.();
}
}, 1000);
}
pause() {
clearInterval(this.timer);
this.duration = this.remaining;
}
stop() {
clearInterval(this.timer);
this.remaining = this.duration;
}
}
// 使用示例
const cd = new Countdown(
30,
(sec) => console.log(`高级剩余: ${sec}秒`),
() => console.log('高级倒计时结束')
);
cd.start();
格式化显示的倒计时
添加时间格式化功能,将秒数转换为 HH:MM:SS 格式。
function formatTime(seconds) {
const hours = Math.floor(seconds / 3600);
const mins = Math.floor((seconds % 3600) / 60);
const secs = seconds % 60;
return [
hours.toString().padStart(2, '0'),
mins.toString().padStart(2, '0'),
secs.toString().padStart(2, '0')
].join(':');
}
// 结合到之前的示例中
countdown(3665, (remaining) => {
console.log(`格式化显示: ${formatTime(remaining)}`);
});
注意事项
- 浏览器标签页处于非激活状态时,
setInterval可能会被节流,导致计时不准 - 使用
requestAnimationFrame可以改善精度但更耗性能 - 清除定时器时务必使用
clearInterval或cancelAnimationFrame - 长时间倒计时应考虑使用服务器时间同步







