首选 setInterval 每秒更新时钟,需确保 DOM 加载完成再执行,用 textContent 而非 innerHTML,格式化推荐 toLocaleTimeString(),后台应监听 visibilitychange 暂停定时器。

直接用 setInterval 每秒调用一次时间更新函数,是最简单、兼容性最好、也最不容易出错的方案。其他方法如 requestAnimationFrame 或事件驱动更新,只在特定场景下有优势,多数项目没必要过早优化。
用 setInterval 实现每秒刷新
这是绝大多数网页实现实时时钟的首选方式,逻辑清晰、浏览器支持全、调试直观。
- 必须确保 DOM 元素已加载完成再执行脚本,否则
document.getElementById会返回null - 推荐把
<script></script>放在</body>前,或包裹在DOMContentLoaded事件里 - 时间格式化建议用
toLocaleTimeString(),它自动适配用户系统语言和时区,比手动拼接更可靠 - 不要用
innerHTML写纯文本时间——改用textContent,避免意外解析 HTML 字符,也更快
为什么不用 requestAnimationFrame?
它确实能对齐屏幕刷新节奏,但用于时钟反而容易引入“跳秒”或“卡顿”错觉,尤其在页面后台运行或 CPU 负载高时。
-
requestAnimationFrame不保证每秒执行 60 次,只保证“下一帧前执行”,实际频率取决于浏览器调度 - 如果只在秒数变化时才更新 DOM,需要额外维护上一秒的缓存值,代码变复杂,收益却极小
- 真正需要它的场景是动画帧同步(比如倒计时进度条+时间文本联动),不是单纯数字跳动
常见错误:时间不更新或初始为空
这基本都是执行时机或元素定位问题,不是逻辑本身有缺陷。
立即学习“前端免费学习笔记(深入)”;
- 脚本放在
<head>里,而目标元素还没解析到 DOM 中 → 报错Cannot set property 'textContent' of null - ID 写错,比如 HTML 是
id="clock",JS 却写成getElementById("time") - 忘记首次调用更新函数,只写了
setInterval,导致页面加载后等 1 秒才出现时间 - 使用了
innerHTML且时间字符串含特殊字符(如冒号被误当 HTML 标签处理),应统一改用textContent
扩展需求:多时区或自定义格式
这些功能加在基础 setInterval 结构上即可,无需换底层机制。
- 显示纽约时间:用
toLocaleTimeString('en-US', { timeZone: 'America/New_York' }) - 输出 “2026年08月26日 星期三 10:35:22”:组合
getFullYear()、getMonth() + 1、getDay()等,注意月份和星期要查表映射(getMonth()返回 0–11,getDay()返回 0–6) - 补零要用
String(n).padStart(2, '0'),别用n < 10 ? '0'+n : n—— 后者在小时为 0 时会变成 "00",但getHours()在 24 小时制下不会返回负数,所以其实安全;但统一用padStart更一致
真正容易被忽略的是页面隐藏时的资源管理:标签页切走后,setInterval 依然在跑,浪费电池和 CPU。加一句 document.addEventListener('visibilitychange', ...) 暂停/恢复定时器,几行代码就能省不少事。



















