坦白说,HTML5 中的 标签并非一个“即插即用”的开箱即用组件。所有涉及播放、暂停以及跳转的逻辑,均需要借助 JavaScript 手动实现。许多初学者误以为只需设置某个属性即可生效,但实际上,每一步都需要准确操作对应的 DOM 元素属性及事件,一旦失误便会徒劳无功。
播放与暂停的核心控制方法
要控制音频的播放与暂停,必须调用相应的方法,单纯修改状态属性是无效的。不少实际项目曾在此处踩过坑。
- play():开始或恢复播放。该方法返回一个 Promise 对象,若调用失败(例如在移动端未获得用户手势授权时),Promise 会被拒绝(reject),但很多时候静默失败不易被察觉。
- pause():暂停播放,不会重置
currentTime。再次调用play()会从暂停位置继续,这一行为与用户直觉一致——点击暂停后再次播放,理应衔接续放。 paused是只读的布尔属性,用于判断当前是否处于暂停状态(包括初始未开始播放的情况)。务必注意,直接赋值audio.paused = false无效,必须老老实实调用play()方法。
进度跳转与实时同步的关键细节
时间控制依赖两个核心属性,但其可用时机存在重要差异。
- currentTime:单位为秒,可读可写。赋值一个数值(例如
audio.currentTime = 42.5),音频会立即跳转。但前提是音频元数据已经加载完毕。 - duration:初始值为
NaN,必须等到loadedmetadata或canplay事件触发后,才能获取到真正的时长。这个问题经常在准备进度条时暴露——数据尚未到达就去读取,自然得到 NaN。 - 监听
timeupdate事件可以获取实时播放位置,适合用来更新进度条或时间显示。但该事件触发频率较高,建议结合防抖或节流处理,否则容易影响性能。 - 拖动进度条时,应先设置
currentTime,再确认音频是否处于播放状态,必要时调用play()恢复播放,否则可能出现“跳转成功但音频仍保持暂停”的问题。
常见失效场景与对应策略
很多时候“点击无效”或“跳转不成功”并非代码写错,而是浏览器策略或加载时机在作祟。
- 移动端自动播放被阻止?请检查是否已添加
muted属性,并且首次调用play()必须由用户手势触发,例如按钮的 click 回调。 - 设置
currentTime不生效?需确认是否在loadedmetadata触发之前执行,或者音频源尚未加载完成时就尝试写入时间。 - 进度条拖拽后无响应?务必绑定
input或change事件,并在回调中显式设置currentTime。许多示例仅绑定了 click,这样是不够的。 - 播放结束但未触发回调?直接监听
ended事件即可,切忌轮询ended属性——那并非该属性的正确用途。
基础控制逻辑的最小可行结构
一个可靠的基础控制流程通常包含以下几个步骤:
- 首先获取 audio 元素的引用(
document.querySelector('audio'))。 - 监听
loadedmetadata事件,获取duration值,同时初始化 UI(例如显示总时长)。 - 为播放/暂停按钮绑定 click 事件,根据
paused状态决定调用play()还是pause()。 - 监听
timeupdate更新当前播放时间,监听ended执行后续动作(如重置按钮文字)。
这些是常用的实践套路,但只有每个细节都精准到位,才能避免那些令人头疼的无声 Bug。

