js实现倒计时
使用 setInterval 实现倒计时
通过 setInterval 定时器每秒更新剩余时间,并在倒计时结束时清除定时器。
function countdown(targetTime, callback) {
const timer = setInterval(() => {
const now = new Date().getTime();
const distance = targetTime - now;
if (distance <= 0) {
clearInterval(timer);
callback(0, 0, 0, 0);
return;
}
const days = Math.floor(distance / (1000 * 60 * 60 * 24));
const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((distance % (1000 * 60)) / 1000);
callback(days, hours, minutes, seconds);
}, 1000);
}
// 示例:倒计时到未来24小时
const targetTime = new Date().getTime() + 24 * 60 * 60 * 1000;
countdown(targetTime, (d, h, m, s) => {
console.log(`${d}天 ${h}小时 ${m}分钟 ${s}秒`);
});
使用 requestAnimationFrame 实现高精度倒计时
适用于需要高精度渲染的场景(如动画),避免 setInterval 的时间漂移问题。
function animationCountdown(targetTime, callback) {
let lastUpdate = 0;
const update = (timestamp) => {
if (timestamp - lastUpdate >= 1000) {
const now = new Date().getTime();
const distance = targetTime - now;
if (distance <= 0) {
callback(0, 0, 0, 0);
return;
}
const days = Math.floor(distance / (1000 * 60 * 60 * 24));
const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((distance % (1000 * 60)) / 1000);
callback(days, hours, minutes, seconds);
lastUpdate = timestamp;
}
requestAnimationFrame(update);
};
requestAnimationFrame(update);
}
使用 Web Worker 实现后台倒计时
避免主线程阻塞,适合长时间运行的倒计时场景。
// worker.js
self.onmessage = function(e) {
const targetTime = e.data;
setInterval(() => {
const now = new Date().getTime();
const distance = targetTime - now;
postMessage(distance > 0 ? distance : 0);
}, 1000);
};
// 主线程代码
const worker = new Worker('worker.js');
worker.postMessage(new Date().getTime() + 5000); // 5秒倒计时
worker.onmessage = (e) => {
console.log(`剩余毫秒数: ${e.data}`);
};
格式化倒计时显示
将毫秒数转换为易读的字符串格式。

function formatCountdown(distance) {
if (distance <= 0) return "00:00:00";
const hours = Math.floor(distance / (1000 * 60 * 60)).toString().padStart(2, '0');
const mins = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)).toString().padStart(2, '0');
const secs = Math.floor((distance % (1000 * 60)) / 1000).toString().padStart(2, '0');
return `${hours}:${mins}:${secs}`;
}
注意事项
- 浏览器标签页休眠时,
setInterval可能被节流,建议用Date对象计算补偿时间。 - 移动端页面隐藏时,
requestAnimationFrame会暂停,需监听visibilitychange事件。 - 跨时区场景需统一使用 UTC 时间处理。






