
本文详解如何通过 javascript 监听 html5 视频播放结束事件,并触发平滑滚动至页面下方目标区域,解决因事件未绑定或逻辑错误导致的滚动失效问题。
在网页中实现“视频播放完毕后自动滚动”是一个常见但易出错的交互需求。你当前代码的核心问题在于:ended() 函数从未被调用,且其内部逻辑与 scrollPlay() 的执行时机存在冲突。此外,直接依赖 vid.currentTime >= vid.duration 判断结束状态在部分浏览器中可能因精度或缓冲问题而不可靠;更健壮的方式是监听原生的 ended 事件。
✅ 正确做法:使用原生 ended 事件监听器
HTML5
const vid = document.getElementById('v0');
// 确保视频加载完成后再绑定事件(推荐在 loadeddata 或 canplaythrough 后)
vid.addEventListener('canplaythrough', () => {
vid.addEventListener('ended', () => {
// ✅ 推荐:平滑滚动到页面底部或指定元素
document.querySelector('.section3').scrollIntoView({
behavior: 'smooth',
block: 'start'
});
// 或滚动到固定像素位置(如 1000px)
// window.scrollTo({ top: 1000, behavior: 'smooth' });
});
});? 提示:canplaythrough 比 loadedmetadata 更稳妥,它表示浏览器认为视频可连续播放而无需中途缓冲,此时绑定 ended 事件更安全。
⚠️ 为什么你原来的代码不工作?
- ended() 函数定义了但从未被调用,也没有绑定到任何事件;
- vid.currentTime >= vid.duration 在 ended 事件触发前就可能为 true(如拖拽、网络延迟),导致误判;
- setInterval 轮询方案(如答案中建议)虽能“兜底”,但属于低效且非标准做法,会持续占用 CPU,且增加代码复杂度;
- scrollPlay() 是一个递归调用 requestAnimationFrame 的函数,用于实现“滚动驱动视频”效果(即滚动控制播放进度),但它与“视频结束滚动”是两个独立需求,混用会导致逻辑混乱和潜在冲突。
✅ 完整修复建议(整合进你的 app.js)
document.addEventListener('DOMContentLoaded', () => {
const vid = document.getElementById('v0');
const setHeight = document.getElementById('set-height');
// 1. 动态设置容器高度(保持原有逻辑)
vid.addEventListener('loadedmetadata', () => {
const playbackConst = 1000;
setHeight.style.height = Math.floor(vid.duration) * playbackConst + 'px';
});
// 2. 启动滚动驱动播放(scrollPlay)——仅当需要“滚动控制视频”时启用
function scrollPlay() {
const frameNumber = window.scrollY / 1000;
if (vid.readyState >= 2) { // 确保有足够数据解码
vid.currentTime = Math.min(frameNumber, vid.duration);
}
requestAnimationFrame(scrollPlay);
}
// 3. 视频播放结束后,停止 scrollPlay 并滚动到下一区域
let scrollPlayActive = false;
vid.addEventListener('play', () => {
if (!scrollPlayActive) {
scrollPlayActive = true;
scrollPlay();
}
});
vid.addEventListener('ended', () => {
scrollPlayActive = false; // 停止驱动逻辑
document.querySelector('.section3').scrollIntoView({
behavior: 'smooth',
block: 'start'
});
});
});? 注意事项
- 不要混用 autoplay 和用户交互限制:现代浏览器(Chrome、Safari 等)要求视频静音(muted)才能自动播放,你已添加 muted,这点正确 ✅;
- 确保目标元素存在:.section3 必须在 DOM 中可访问,否则 scrollIntoView() 会静默失败;
- 避免重复绑定:将事件监听器放在 DOMContentLoaded 内,防止脚本多次执行导致重复监听;
- 移动端兼容性:scrollIntoView({ behavior: 'smooth' }) 在所有现代浏览器中均支持;若需兼容旧版 Safari,可降级为 window.scrollTo(0, target.offsetTop)。
✅ 总结
实现“视频结束自动滚动”的关键不是轮询或手动比对时间,而是信任并正确使用 HTML5 视频的原生事件系统。只需监听 ended 事件,在回调中调用 scrollIntoView() 或 scrollTo() 即可。同时注意分离不同功能逻辑(如“滚动驱动播放”与“结束跳转”),保持代码清晰、可维护、高性能。










