在前端开发场景中,倒计时功能是非常常见的需求,比如电商活动开售倒计时、考试剩余时间提醒、短信验证码倒计时等,都可以通过JavaScript来实现。实现倒计时的核心逻辑是获取目标时间和当前时间的差值,再通过定时器每隔固定时间更新一次剩余时间,直到差值归零。

JS倒计时的核心实现原理
倒计时的实现依赖两个关键部分,一是时间差的计算,二是定时器的使用。时间差计算需要用到Date对象,通过获取目标时间戳和当前时间戳的差值,得到剩余的毫秒数,再将毫秒数转换为天、时、分、秒等可读性更强的单位。定时器的选择上,通常使用setInterval每隔1秒执行一次更新逻辑,当剩余时间归零时清除定时器。
时间单位转换规则
1秒等于1000毫秒,转换时按照以下公式计算:
- 剩余天数 = 剩余毫秒数 / (1000 * 60 * 60 * 24),向下取整
- 剩余小时 = (剩余毫秒数 % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60),向下取整
- 剩余分钟 = (剩余毫秒数 % (1000 * 60 * 60)) / (1000 * 60),向下取整
- 剩余秒数 = (剩余毫秒数 % (1000 * 60)) / 1000,向下取整
基础倒计时功能实现代码
下面是一个简单的倒计时实现示例,目标时间是当前时间往后推10分钟,页面会显示剩余的分和秒:
// 定义目标时间,这里设置为当前时间加10分钟
const targetTime = new Date().getTime() + 10 * 60 * 1000;
// 获取显示倒计时的DOM元素
const countdownEl = document.getElementById('countdown');
// 定义更新倒计时的函数
function updateCountdown() {
// 获取当前时间戳
const now = new Date().getTime();
// 计算剩余毫秒数
const diff = targetTime - now;
// 如果剩余时间小于等于0,清除定时器并显示结束提示
if (diff <= 0) {
clearInterval(timer);
countdownEl.innerHTML = '倒计时结束';
return;
}
// 转换剩余时间为分和秒
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((diff % (1000 * 60)) / 1000);
// 补零处理,保证显示格式为两位数字
const formatMinutes = minutes < 10 ? '0' + minutes : minutes;
const formatSeconds = seconds < 10 ? '0' + seconds : seconds;
// 更新页面显示
countdownEl.innerHTML = `剩余时间:${formatMinutes}分${formatSeconds}秒`;
}
// 先执行一次更新,避免页面初始显示空白
updateCountdown();
// 设置定时器,每隔1秒执行一次更新
const timer = setInterval(updateCountdown, 1000);
页面中的实际应用优化
处理页面后台运行的时间偏差
如果页面切换到后台,setInterval的执行间隔可能会变长,导致倒计时出现偏差。可以在每次更新时重新计算当前时间和目标时间的差值,而不是直接递减固定的秒数,上面的基础代码已经采用了这种方式,能有效避免偏差问题。
倒计时结束后的业务处理
很多场景下倒计时结束后需要触发对应操作,比如跳转到活动页、显示提示弹窗等,可以在倒计时归零的逻辑中添加对应的代码:
// 倒计时结束后的处理逻辑
if (diff <= 0) {
clearInterval(timer);
countdownEl.innerHTML = '活动已开始';
// 这里可以添加跳转逻辑或者其他业务操作
// window.location.href = 'https://ipipp.com/activity';
return;
}
验证码倒计时场景实现
短信验证码的倒计时通常是点击按钮后开始,倒计时期间按钮不可点击,倒计时结束后恢复可点击状态,实现代码如下:
// 获取验证码按钮元素
const codeBtn = document.getElementById('codeBtn');
// 定义倒计时总时长,单位秒
const totalSeconds = 60;
let codeTimer = null;
let remainSeconds = totalSeconds;
// 点击按钮触发倒计时
codeBtn.addEventListener('click', function() {
// 防止重复点击
if (codeTimer) return;
// 按钮置为不可点击状态
codeBtn.disabled = true;
codeBtn.innerHTML = `${remainSeconds}秒后重新获取`;
// 启动定时器
codeTimer = setInterval(function() {
remainSeconds--;
codeBtn.innerHTML = `${remainSeconds}秒后重新获取`;
// 倒计时结束
if (remainSeconds <= 0) {
clearInterval(codeTimer);
codeTimer = null;
remainSeconds = totalSeconds;
// 恢复按钮可点击状态
codeBtn.disabled = false;
codeBtn.innerHTML = '获取验证码';
}
}, 1000);
});
常见问题与注意事项
- 不要使用
setTimeout递归代替setInterval,虽然也能实现效果,但setInterval的逻辑更简洁,只要注意在不需要的时候及时清除即可。 - 时间转换时要注意向下取整,避免出现小数导致显示异常。
- 页面卸载前最好清除所有定时器,避免内存泄漏,可以在
beforeunload事件中处理。 - 如果目标时间是固定的未来时间,比如活动开售时间,不需要每次都重新计算目标时间戳,只需要在初始化的时候计算一次即可。
JavaScriptJS倒计时timer页面交互修改时间:2026-06-25 01:12:32