HTML5动画如何添加计时器功能_HTML5倒计时/计时实现【计时指南】
发布时间 - 2026-01-05 00:00:00 点击率:次应使用时间戳校准法而非固定毫秒间隔:记录起始时间,每次渲染时用Date.now()计算剩余时间,每100ms更新一次,并结合Page Visibility API处理页面失焦、requestAnimationFrame实现高精度计时、服务端时间兜底防篡改。
用 setInterval 实现基础倒计时,但别直接写死毫秒数
HTML5 本身不提供内置计时器组件,所有倒计时/计时功能都依赖 JavaScript 的 setInterval 或 setTimeout。直接写 setInterval(() => { sec-- }, 1000) 看似可行,但实际会因任务队列延迟、页面失焦暂停、JS 执行阻塞等问题导致误差累积——5 分钟后可能差 3–8 秒。
更可靠的做法是记录起始时间戳,每次渲染时计算剩余毫秒数:
let startTime = Date.now(); let durationMs = 5 * 60 * 1000; // 5分钟function updateTimer() { const elapsed = Date.now() - startTime; const remaining = Math.max(0, durationMs - elapsed); const mins = Math.floor(remaining / 60000); const secs = Math.floor((remaining % 60000) / 1000); document.getElementById('timer').textContent =
${mins}:${secs.toString().padStart(2, '0')};if (remaining <= 0) { clearInterval(timerId); } }
const timerId = setInterval(updateTimer, 100); // 每100ms校准一次,平衡精度与性能
- 用
Date.now()而非new Date().getTime(),前者更快更轻量 - 间隔设为
100而非1000,避免用户看到“跳秒”;人眼对 100ms 级更新无感,但能保证显示值始终准确 - 务必在结束时调用
clearInterval(timerId),否则定时器持续运行,造成内存泄漏
页面后台运行时倒计时暂停?用 Page Visibility API 补救
Chrome/Firefox/Safari 在标签页不可见时会降频甚至暂停 setInterval,导致倒计时“卡住”。用户切回页面才发现已超时 2 分钟。
立即学习“前端免费学习笔记(深入)”;
用 document.visibilityState 监听页面可见性,在隐藏时暂停逻辑,在显示时重新校准:
let isPaused = false; let pausedAt = 0;document.addEventListener('visibilitychange', () => { if (document.hidden) { isPaused = true; pausedAt = Date.now(); } else if (isPaused) { isPaused = false; startTime += Date.now() - pausedAt; // 补上挂起时间 } });
- 不要依赖
blur/focus事件——它们在 iframe、弹窗、开发者工具打开时也会误触发 -
visibilitychange是唯一被所有现代浏览器稳定支持的页面可见性检测机制 - 补时间不能简单加固定值,必须用
Date.now()计算真实挂起时长
需要高精度计时(如秒表)?避开 setInterval 改用 requestAnimationFrame
当倒计时用于运动动画同步、音频节拍或实验室级计时场景时,setInterval 的抖动(±10–30ms)不可接受。此时应改用 requestAnimationFrame 驱动,它与屏幕刷新率绑定(通常 60fps),误差可压到 ±1ms 内。
let startTime = Date.now(); let lastTime = startTime; let elapsed = 0;function tick(timestamp) { if (!lastTime) lastTime = timestamp; const delta = timestamp - lastTime; elapsed += delta; lastTime = timestamp;
const displaySec = (elapsed / 1000).toFixed(2); documen
t.getElementById('stopwatch').textContent = displaySec;
if (isRunning) requestAnimationFrame(tick); }
-
requestAnimationFrame不受页面是否可见影响,但会在页面完全冻结(如系统休眠)时停止——这反而是合理行为 - 必须用
timestamp参数(而非Date.now())计算增量,它是浏览器提供的高精度单调时间源 - 注意:它不自动循环,需手动递归调用
requestAnimationFrame(tick)
倒计时结束要触发动作?别只靠定时器,加一层服务端时间兜底
纯前端倒计时最大的风险是用户篡改本地时间或设备时钟。比如把系统时间调快 1 小时,就能绕过 30 分钟答题限制。
关键操作(如提交、解锁、支付)必须和服务端时间比对。前端只负责 UI 提示,真正判断依据是服务端返回的 expires_at 时间戳:
// 假设接口返回 { expires_at: "2025-06-15T14:30:00Z" }
const serverExpires = new Date(response.expires_at).getTime();
function checkDeadline() {
const now = Date.now();
const remaining = Math.max(0, serverExpires - now);
if (remaining <= 0) {
alert('已超时,请刷新重试');
return false;
}
return true;
}
- 前端倒计时显示可以继续用本地时间(体验好),但“是否允许操作”的判断必须查
serverExpires - 服务端时间要用 UTC 格式(带
Z后缀),避免时区解析歧义 - 首次加载时就请求一次服务端时间,用它校准本地
Date.now()偏差,能进一步提升精度
前端倒计时看着简单,真正难的是处理页面失焦、时钟篡改、高帧率同步、服务端一致性这些边缘情况。多数项目卡在“能跑”和“可靠”之间,差的就是这几行校准和兜底逻辑。
# javascript
# java
# html
# js
# 前端
# html5
# 浏览器
# 工具
# safari
# ai
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
微信h5制作网站有哪些,免费微信H5页面制作工具?
JS碰撞运动实现方法详解
Laravel如何安装使用Debugbar工具栏_Laravel性能调试与SQL监控插件【步骤】
UC浏览器如何设置启动页 UC浏览器启动页设置方法
如何用西部建站助手快速创建专业网站?
东莞市网站制作公司有哪些,东莞找工作用什么网站好?
Swift中循环语句中的转移语句 break 和 continue
实例解析angularjs的filter过滤器
东莞专业网站制作公司有哪些,东莞招聘网站哪个好?
制作企业网站建设方案,怎样建设一个公司网站?
javascript中的try catch异常捕获机制用法分析
php后缀怎么变mp4格式错误_修改扩展名提示格式不对怎么办【技巧】
html5如何实现懒加载图片_ intersectionobserver api用法【教程】
如何获取免费开源的自助建站系统源码?
如何在云主机上快速搭建网站?
网站制作大概多少钱一个,做一个平台网站大概多少钱?
如何正确下载安装西数主机建站助手?
Linux虚拟化技术教程_KVMQEMU虚拟机安装与调优
香港服务器租用每月最低只需15元?
如何在IIS7中新建站点?详细步骤解析
简历在线制作网站免费版,如何创建个人简历?
猎豹浏览器开发者工具怎么打开 猎豹浏览器F12调试工具使用【前端必备】
制作电商网页,电商供应链怎么做?
免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?
网页制作模板网站推荐,网页设计海报之类的素材哪里好?
如何在IIS管理器中快速创建并配置网站?
Laravel怎么在Controller之外的地方验证数据
Python文件流缓冲机制_IO性能解析【教程】
深入理解Android中的xmlns:tools属性
个人网站制作流程图片大全,个人网站如何注销?
JavaScript实现Fly Bird小游戏
Laravel如何优雅地处理服务层_在Laravel中使用Service层和Repository层
网站建设整体流程解析,建站其实很容易!
Windows11怎样设置电源计划_Windows11电源计划调整攻略【指南】
如何将凡科建站内容保存为本地文件?
网站制作软件有哪些,制图软件有哪些?
软银砸40亿美元收购DigitalBridge 强化AI资料中心布局
如何在建站宝盒中设置产品搜索功能?
如何批量查询域名的建站时间记录?
Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程
Laravel如何使用Scope本地作用域_Laravel模型常用查询逻辑封装技巧【手册】
如何快速搭建安全的FTP站点?
Laravel distinct去重查询_Laravel Eloquent去重方法
齐河建站公司:营销型网站建设与SEO优化双核驱动策略
如何在腾讯云服务器上快速搭建个人网站?
Laravel怎么配置自定义表前缀_Laravel数据库迁移与Eloquent表名映射【步骤】
网站设计制作书签怎么做,怎样将网页添加到书签/主页书签/桌面?
哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?
Laravel如何配置和使用缓存?(Redis代码示例)
装修招标网站设计制作流程,装修招标流程?


t.getElementById('stopwatch').textContent = displaySec;