用js实现一个倒计时器
实现倒计时器的基本方法
使用JavaScript实现倒计时器可以通过setInterval或requestAnimationFrame结合时间差计算来完成。以下是两种常见的实现方式。

基于setInterval的倒计时器
创建一个简单的倒计时器,显示剩余时间并支持暂停和重置功能。
class CountdownTimer {
constructor(duration, displayElement) {
this.duration = duration; // 总时长(秒)
this.displayElement = displayElement;
this.remainingTime = duration;
this.timerId = null;
}
start() {
if (this.timerId) return;
this.timerId = setInterval(() => {
this.remainingTime--;
this.updateDisplay();
if (this.remainingTime <= 0) {
this.stop();
}
}, 1000);
}
stop() {
clearInterval(this.timerId);
this.timerId = null;
}
reset() {
this.stop();
this.remainingTime = this.duration;
this.updateDisplay();
}
updateDisplay() {
const minutes = Math.floor(this.remainingTime / 60);
const seconds = this.remainingTime % 60;
this.displayElement.textContent = `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
}
}
// 使用示例
const display = document.getElementById('countdown-display');
const timer = new CountdownTimer(300, display); // 5分钟倒计时
document.getElementById('start-btn').addEventListener('click', () => timer.start());
document.getElementById('stop-btn').addEventListener('click', () => timer.stop());
document.getElementById('reset-btn').addEventListener('click', () => timer.reset());
基于requestAnimationFrame的高精度倒计时器
如果需要更高精度或更流畅的动画效果,可以使用requestAnimationFrame。
class HighPrecisionCountdown {
constructor(duration, displayElement) {
this.duration = duration * 1000; // 转换为毫秒
this.displayElement = displayElement;
this.startTime = null;
this.remainingTime = this.duration;
this.animationId = null;
}
start() {
if (this.animationId) return;
this.startTime = performance.now();
this.animationId = requestAnimationFrame(this.update.bind(this));
}
update(timestamp) {
const elapsed = timestamp - this.startTime;
this.remainingTime = Math.max(0, this.duration - elapsed);
this.render();
if (this.remainingTime > 0) {
this.animationId = requestAnimationFrame(this.update.bind(this));
}
}
stop() {
cancelAnimationFrame(this.animationId);
this.animationId = null;
}
reset() {
this.stop();
this.remainingTime = this.duration;
this.render();
}
render() {
const totalSeconds = Math.ceil(this.remainingTime / 1000);
const minutes = Math.floor(totalSeconds / 60);
const seconds = totalSeconds % 60;
this.displayElement.textContent = `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
}
}
// 使用示例
const display = document.getElementById('high-precision-countdown');
const highPrecisionTimer = new HighPrecisionCountdown(300, display);
document.getElementById('start-btn').addEventListener('click', () => highPrecisionTimer.start());
document.getElementById('stop-btn').addEventListener('click', () => highPrecisionTimer.stop());
document.getElementById('reset-btn').addEventListener('click', () => highPrecisionTimer.reset());
注意事项
setInterval可能存在时间漂移问题,长时间运行后可能不准确。requestAnimationFrame更适合需要平滑动画的场景,但会消耗更多资源。- 页面不可见时(如切换到其他标签页),
requestAnimationFrame会暂停执行,而setInterval可能继续运行但会被浏览器限制。







