纯 HTML + JavaScript 可实现 H5 答题闯关游戏,需手动管理状态流转、题库加载、计时与 DOM 切换;题库宜用 JS 对象数组定义,含 id、question、options、answer、timeLimit 字段;倒计时须基于 performance.now() 锚点计算,页面隐藏时暂停并恢复;答题后立即禁用选项、验证、反馈、再跳转;DOM 显隐用 classList 控制;中断时 via beforeunload 保存进度。

纯 HTML + JavaScript 就能做出可运行的 H5 答题闯关游戏,不需要框架、不依赖构建工具,但必须手动处理状态流转、题库加载、计时逻辑和 DOM 切换——否则页面会卡顿、答题状态错乱、倒计时不准。
怎么组织题库数据结构才方便切换题目
题库不能写死在 HTML 里,也不能每次点击都重新 fetch;推荐用 JS 对象数组直接定义,每道题包含 id、question、options(数组)、answer(索引或值)、timeLimit(秒)等字段。这样后续加「跳过」「回看」功能时,只需操作数组下标,不用反复查 DOM。
常见错误是把选项写成 <input type="radio"> 后靠 name 分组,结果第 2 关刷新后选中状态残留——因为没清空 checked 属性。正确做法是每次渲染新题时,用 JS 显式设置 input.checked = false,或直接用 <button></button> 模拟选项,避免原生表单干扰。
- 选项值建议统一用字符串(如
"A"、"B"),别混用数字和字母,否则===判断易出错 - 如果题干含 HTML(比如公式、图片),
question字段要用innerHTML渲染,但必须确保内容可信,否则有 XSS 风险 - 不要把题库存在
localStorage里再读取,首次加载就同步定义好,减少异步等待
倒计时怎么写才不会 drift(漂移)
用 setTimeout 递归或 setInterval 做倒计时,10 秒后误差可能达 300ms 以上,尤其在页面切到后台再切回时。真实场景下必须用 performance.now() 或 Date.now() 做时间锚点,每次渲染前计算剩余毫秒数。
立即学习“前端免费学习笔记(深入)”;
示例逻辑:启动时记录 startTime = performance.now(),在 requestAnimationFrame 回调里算 elapsed = (performance.now() - startTime) / 1000,再用 Math.max(0, Math.ceil(timeLimit - elapsed)) 更新显示。这样即使中间有帧丢弃,倒计时依然准确。
- 别在
setInterval(fn, 1000)里直接second--,系统调度不保证准时 - 页面不可见时(
document.hidden === true),要暂停计时器并保存已耗时,切回前台再继续,否则用户切微信聊完天回来发现题已超时 - 倒计时到 0 必须立刻触发提交逻辑,不能等下一次回调,防止用户狂点选项卡住
如何判断用户答对且平滑进入下一关
点击选项后不能立即跳转,得等动画结束(如有)、提交请求返回(如有后端校验)、或本地验证完成。最简方案是:禁用所有选项按钮 → 执行验证 → 显示对错反馈(比如高亮正确答案 1.2 秒)→ 再自动跳转。关键在「禁用」这一步,否则用户连点两次会触发两次跳转,currentQuestionIndex 加了两次,直接跳过一题。
如果要做「闯关」感,下一关不是简单 index++,而是检查 score >= passScore 或 streak >= 3 等条件;失败时显示「再练一题」按钮,而不是强制重来。
- 验证逻辑必须放在点击事件内,别写在外部函数里还漏传参数,容易出现
undefined is not an object - DOM 切换用
classList.add/remove控制显隐,别用display: none反复 setStyle,影响重排 - 如果用 CSS 动画做「翻页」效果,监听
animationend事件再加载下一题,比 setTimeout 更可靠
最常被忽略的是「中断流程」:用户中途关闭页面、网络断开、手机锁屏——这些情况不会触发你写的任何回调。真要健壮,得在 beforeunload 存当前关卡和得分,恢复时优先读这个,而不是无脑从第 1 关开始。



















