最稳妥的起点是用 setinterval 每秒调用 new date() 更新 dom,但会因主线程卡顿导致跳秒;应改用 requestanimationframe + date.now() 校准时间,用 textcontent 而非 innerhtml,手动拼接时间字符串而非 tolocaletimestring(),并确保 dom 元素已加载。

直接用 setInterval 每秒调用一次 new Date() 并更新 DOM 是最稳妥的起点,但要注意它不保证“整秒触发”,且容易因主线程卡顿导致跳秒——这不是 bug,是浏览器行为本身决定的。
为什么 setInterval(updateTime, 1000) 会跳秒?
setInterval 只是“尽量每 1000ms 调用一次”,实际执行时间取决于 JS 主线程是否空闲。如果页面正在跑 heavy 计算、渲染大量 DOM 或触发长任务,回调就会被推迟,造成连续两秒甚至三秒才更新一次。
- 现象:时间从
10:49:59直接跳到10:50:01,中间漏掉一秒 - 解决思路不是“提高频率”,而是改用
requestAnimationFrame+ 时间差校准 - 关键点:每次执行时用
Date.now()获取真实毫秒数,再手动计算“该显示哪一秒”,而不是依赖定时器节奏
textContent 比 innerHTML 更安全也更快
如果你只显示纯时间字符串(比如 "10:50:23"),千万别用 innerHTML 写入。它会触发 HTML 解析、DOM 构建和样式重排,开销大,还可能意外执行脚本(万一时间字符串里混入了恶意字符)。
- 正确写法:
element.textContent = formattedTime - 错误写法:
element.innerHTML = formattedTime(除非你明确需要渲染 HTML 标签) - 性能差异在低端设备上尤其明显;
textContent是纯文本赋值,无解析成本
toLocaleTimeString() 看似方便,但有隐藏陷阱
toLocaleTimeString() 能自动适配用户系统设置(如 12/24 小时制、AM/PM、千位分隔符),但它的输出不可预测:中文系统可能返回 "上午10:50:23",英文系统是 "10:50:23 AM",而某些地区还会带秒以下精度或时区缩写。
- 适合场景:仅作内部状态提示、无需格式统一的后台页面
- 不适合场景:需要固定宽度对齐的数字时钟、要提取小时做逻辑判断、SEO 需要结构化时间
- 更可控的替代:用
getHours()+padStart(2, '0')手动拼接,完全掌握每一位输出
DOM 元素必须存在,且 script 放对位置
常见错误是脚本执行时目标元素还没加载出来,结果 document.getElementById('clock') 返回 null,后续调用 .textContent 直接报错 Cannot set property 'textContent' of null。
- 最简单解法:把
<script></script>放在
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











