onended事件必须用addeventlistener绑定,内联onended属性在现代浏览器中基本无效;需等待loadedmetadata或canplaythrough后绑定,并注意ios safari的兼容性问题。

onended 事件绑定必须用 addEventListener
直接写 onended 属性在现代浏览器里基本无效——它只对部分原生 <audio></audio> 或 <video></video> 元素的内联属性写法有微弱支持,且无法可靠触发。真实项目里得用 JS 的 addEventListener。
常见错误是这么写:<video onended="handleEnd()"></video>,但函数不会执行,控制台也不报错,纯静默失败。
- 必须先拿到 DOM 元素,比如
const video = document.querySelector('video'); - 然后绑定:
video.addEventListener('ended', handleEnd);(注意别加括号,传函数引用) - 如果用了 React/Vue 等框架,不要在 JSX 或模板里写
onended,统一在useEffect或mounted里用addEventListener
为什么 ended 不像 click 那样“即插即用”
ended 是媒体元素的**异步完成事件**,依赖播放状态、缓冲、编码格式甚至硬件解码能力。它不像 click 那样由用户动作即时触发,所以时机和可靠性更敏感。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 如果视频中途被
pause()或load()中断,ended永远不会触发 - HLS 或 DASH 流媒体几乎不触发
ended,因为它们没有明确“结束”,得靠timeupdate+duration判断 - 某些 MP4 文件因 moov box 位置靠后,可能播放完才触发
ended,造成延迟
监听前必须确保元素已加载元数据
如果在 DOMContentLoaded 时就绑 ended,但 video 的 src 还没加载完,事件监听器会挂上,但后续播放仍可能漏掉事件——尤其当 src 是动态设置的。
- 稳妥做法:等
loadedmetadata触发后再绑定ended - 示例:
video.addEventListener('loadedmetadata', () => { video.addEventListener('ended', handleEnd); }); - 或者更激进一点:用
canplaythrough,表示足够缓冲到结尾,这时再绑也来得及
移动端 iOS Safari 的 ended 坑最多
iOS 上 ended 在自动播放被限制、用户未交互过、或使用 playsinline 但未加 webkit-playsinline 时,大概率不触发。
- 必须加这两个属性:
playsinline和webkit-playsinline - 首次播放必须由用户手势触发(比如点击按钮),否则整个媒体生命周期不可靠
- 测试时别只看 Chrome,真机连上 Safari 开发者工具查
console.log是否输出,别信模拟器
ended、pause、timeupdate,再结合 currentTime 和 duration 手动兜底判断是否真的播完了。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










