- ```html
倒计时 · 代码手记 html网页倒计时代码
倒计时不是靠setInterval硬算的。大多数人写倒计时,倒计直接每秒减1,时代结果页面一卡就错位。网页真正的倒计核心是:用目标时间戳减去当前时间戳,再换算成天时分秒。时代这样哪怕浏览器休眠了十分钟,网页回来照样准。倒计
我手头有个活动页,时代要求倒计时到2025年元旦。网页第一版代码长这样:
<div id="timer">00:00:00:00</div> <script> const target = new Date('2025-01-01T00:00:00').getTime(); function update() { const now = Date.now(); let diff = target - now; if (diff < 0) diff = 0; const days = Math.floor(diff / (1000*60*60*24)); const hours = Math.floor((diff / (1000*60*60)) % 24); const mins = Math.floor((diff / (1000*60)) % 60); const secs = Math.floor((diff / 1000) % 60); document.getElementById('timer').textContent = `${ String(days).padStart(2,倒计'0')}:${ String(hours).padStart(2,'0')}:${ String(mins).padStart(2,'0')}:${ String(secs).padStart(2,'0')}`; } update(); setInterval(update, 1000); </script>这段代码能跑,但有个隐患——
setInterval在浏览器标签页后台时会被节流,时代最低每秒一次甚至降到每分钟一次。网页如果用户切到别的倒计标签页再回来,中间跳变好几秒,时代视觉上很难看。更好的做法是每次触发更新时重新计算当前时间,而不是累加。上面代码已经这么干了,所以其实后台回来也会自动校正。但有个细节:
setInterval间隔设1000毫秒,实际可能因为事件循环延迟变成1005毫秒或更久。没关系,因为每次都是重新算差值,误差不会累积。关键坑在哪?——时间字符串的格式化。有人用
new Date(diff)然后getUTCHours(),但diff是毫秒差,不是从1970年开始的日期。如果你直接new Date(diff),得到的是1970-01-01T00:00:00.xxx加diff毫秒,当天数超过24小时就会溢出到月份甚至年份,完全乱掉。所以必须手动拆分成天、小时、分钟、秒。我见过一个真实案例:某电商促销页把
diff当时间戳传给new Date(),然后取getHours()。结果倒计时显示“20小时”而不是“3天4小时”,用户以为活动当天就结束,投诉电话打爆。那个程序员没意识到Date对象本身带有时区,而且它的“小时”部分最大值是23。另一个细节:倒计时结束后要做什么。很多人只写
if(diff <= 0) clearInterval(),但忘了显示“已结束”或者跳转。我习惯在diff小于等于0时,把计时器文本改为“活动已开始”,同时用clearInterval停掉定时器,防止无用的计算。还有,如果目标时间在页面加载时已经过了,直接显示结束文案,不要先闪一下“00:00:00:00”。个人建议:把目标时间写在
data-*属性里,比如<div data-countdown="2025-06-01T00:00:00">,然后用一个脚本统一处理页面所有倒计时。这样改时间不用碰JS,运营自己改HTML就行。我做过一个专题页有五个倒计时,分别指向不同场的秒杀,用这种方式管理,后期零维护。关于精度:如果只是展示到秒,每秒更新一次足矣。但如果你要显示毫秒(比如抽奖抢购),就得用
requestAnimationFrame代替setInterval。因为rAF跟随屏幕刷新率,通常60fps,而且后台自动暂停,不会浪费资源。但要注意,rAF回调里需要自己判断时间差是否超过50ms才更新DOM,否则每秒重绘60次没意义。最后说个容易忽略的点——时区问题。如果目标时间用
new Date('2025-01-01T00:00:00'),这个字符串不带时区,浏览器会按本地时间解析。如果服务器在美国,用户在中国,那么活动实际开始时间会差13小时。要统一就用new Date('2025-01-01T00:00:00+08:00')强制指定东八区,或者用时间戳(毫秒数)写死,不依赖字符串解析。写倒计时最爽的时刻是什么?是你加了一个
visibilitychange事件监听,当用户切回页面时立刻调用一次update(),瞬间校正时间。那种“一切尽在掌握”的感觉,比任何框架都踏实。代码不在多,把时间戳算准,把边界条件处理干净,就完事了。
—— 写于一个刚改完倒计时的下午
``` 顶: 8踩: 14136






评论专区