onloadeddata仅表示当前播放位置首帧数据就绪,不可用于获取时长或自动播放;应改用onloadedmetadata读取元数据、oncanplay确保可播放。

onloadeddata 不是“加载完”的信号,它只表示**当前播放位置那一帧的数据已就绪**,但远不足以保证能播、能跳转、甚至不一定知道视频有多长。别把它当 onload 或 canplay 用。
为什么 onloadeddata 容易被误用
常见错误现象:绑定 onloadeddata 后立刻读 video.duration,结果是 NaN 或 0;或者调用 play() 报 NotAllowedError;又或者隐藏 loading 图标后画面卡住——这些都不是 bug,是时机错了。
根本原因:onloadeddata 触发时,浏览器只解码并准备好**当前帧(通常是第一帧)的像素数据**,元数据(如时长、宽高)还没解析完,网络缓冲也几乎为零。
- 它发生在
onloadedmetadata之后、oncanplay之前 -
video.readyState此时通常是1(HAVE_CURRENT_DATA),不是4(HAVE_ENOUGH_DATA) - 对 HLS/DASH 流或未 fast-start 的 MP4,
onloadeddata可能比onloadedmetadata还早触发
onloadeddata 真正该干的事
它唯一可靠的作用,就是告诉你:“首帧图像现在可以渲染了”。适合做视觉层面的轻量响应,比如:
- 隐藏 placeholder 或 loading 动画(只要你想在首帧出现时就切走)
- 启用截图按钮(
canvas.drawImage(video, ...)现在安全了) - 记录首帧渲染时间(用于性能监控,不是加载完成时间)
- 触发一次
requestVideoFrameCallback(如果需要精确帧处理)
示例:
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
const video = document.getElementById('myVideo');
video.onloadeddata = () => {
// ✅ 安全:首帧已就绪,可截图或隐藏 loading
document.querySelector('.loading-overlay').style.display = 'none';
// ❌ 危险:duration/videoWidth 很可能还是 0 或 NaN
console.log(video.duration); // 大概率是 NaN
};
替代方案:什么时候该用哪个事件
按真实需求选,别硬套 onloadeddata:
- 要读
video.duration、video.videoWidth?→ 绑定onloadedmetadata,且检查isFinite(video.duration) - 要自动播放或确保能播?→ 用
oncanplay或oncanplaythrough,后者更保守 - 要等所有资源(图片、字体、JS)加载完?→ 用
window.onload,但通常没必要 - 只想等 DOM 就绪?→ 用
DOMContentLoaded,和媒体加载无关
注意:onloadedmetadata 必须在设置 src 前或后立即绑定,否则可能错过——尤其 SSR 渲染或动态插入 video 元素时。
兼容性和陷阱提醒
IE 8 及更早版本不支持 onloadeddata,不过现在基本不用考虑。真正容易被忽略的是:
- 某些 MP4 文件没把
moovbox 放开头,会导致onloadedmetadata和onloadeddata都严重延迟,甚至失败 - 设置了
preload="none"时,onloadeddata可能永远不会触发,除非用户点播放 - 用
URL.createObjectURL(blob)创建的视频源,事件触发时机与 blob 加载状态强相关,需额外监听blob加载完成
如果你发现 onloadeddata 没触发,先检查是不是 preload 策略或文件结构问题,而不是代码写错了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










