
本文详解如何监听 HTML5 视频(`
在开发中,常需实现“视频驱动滚动”效果——即视频播放进度与页面滚动位置同步,且在视频自然结束时,自动跳转至指定区域(如表单、CTA 按钮或下一章节)。你提供的代码存在几个关键问题,导致 ended 函数从未被调用,也无法可靠检测播放结束状态。下面我们将从原理到实践,给出清晰、专业、可落地的解决方案。
✅ 正确监听视频结束:优先使用 ended 事件
HTML5
const vid = document.getElementById('v0');
// ✅ 推荐:直接监听 ended 事件
vid.addEventListener('ended', () => {
console.log('视频已播放完毕');
// 平滑滚动至页面某处(例如 section3 的顶部)
document.querySelector('.section3').scrollIntoView({
behavior: 'smooth',
block: 'start'
});
});⚠️ 注意:你的原始代码中定义了 function ended(){...},但从未注册该函数为事件处理器,也未调用它。JS 不会自动执行未绑定的函数。
❌ 为什么 vid.onended = function(){...} 可能失效?
虽然 vid.onended = ... 语法合法,但它属于旧式内联事件处理方式,存在两个隐患:
立即学习“Java免费学习笔记(深入)”;
- 若其他代码(如框架、第三方脚本)后续再次赋值 vid.onended,会覆盖你的逻辑;
- 它不支持添加多个监听器(而 addEventListener 支持)。
✅ 始终优先使用 addEventListener('ended', handler)。
? 关于 scrollPlay() 的注意事项(与滚动联动相关)
你当前的 scrollPlay() 是一个基于 requestAnimationFrame 的滚动驱动播放逻辑,设计初衷是“滚动 → 控制视频时间”。但注意:
- 它在 ended 函数中被无条件调用,而此时视频已结束,继续调用可能干扰状态;
- vid.currentTime >= vid.duration 在 ended 事件触发时必然为真,无需重复判断;
- 若你同时启用滚动驱动 + 自动跳转,建议在 ended 中先停止动画循环(如有),再执行跳转。
示例增强版(含清理):
let scrollAnimId = null;
function scrollPlay() {
const scrollY = window.scrollY;
const frameNumber = scrollY / playbackConst;
vid.currentTime = Math.min(frameNumber, vid.duration); // 防止超限
scrollAnimId = requestAnimationFrame(scrollPlay);
}
// 启动滚动驱动(例如在页面加载后)
scrollPlay();
// 视频结束:停止驱动动画 + 平滑跳转
vid.addEventListener('ended', () => {
if (scrollAnimId) {
cancelAnimationFrame(scrollAnimId);
scrollAnimId = null;
}
document.querySelector('.section3').scrollIntoView({ behavior: 'smooth' });
});? 补充:确保 DOM 就绪 & 视频可读取
为避免 getElementById 返回 null,请将 JS 逻辑包裹在 DOM 加载完成回调中:
document.addEventListener('DOMContentLoaded', () => {
const vid = document.getElementById('v0');
if (!vid) return;
// 设置高度(可选优化)
vid.addEventListener('loadedmetadata', () => {
const setHeight = document.getElementById("set-height");
if (setHeight) {
setHeight.style.height = Math.floor(vid.duration) * playbackConst + "px";
}
});
// 绑定 ended 事件
vid.addEventListener('ended', () => {
document.querySelector('.section3').scrollIntoView({ behavior: 'smooth' });
});
});✅ 最终推荐结构(简洁可靠)
? 提示:确保目标元素(如
)真实存在于 DOM 中,否则 scrollIntoView() 无效果。? 总结
- ✅ 使用 video.addEventListener('ended', handler) 是监听视频结束的标准、高效、推荐方式;
- ❌ 不要定义未调用的函数(如孤立的 ended()),也不要依赖轮询检测;
- ⚙️ 若同时实现“滚动控制视频”,需在 ended 中主动清理 requestAnimationFrame 循环;
- ?️ 总是检查 DOM 元素是否存在,用 DOMContentLoaded 确保执行时机;
- ? scrollIntoView({ behavior: 'smooth' }) 提供原生平滑滚动,兼容现代浏览器(Can I use)。
按此方案调整后,视频一结束,页面将立即、平滑地滚动至你指定的位置——简洁、健壮、符合 Web 标准。










