如何实现N个视频预加载2秒内容后的触发响应逻辑
如何实现N个视频预加载2秒内容后的触发响应逻辑
这个需求其实挺贴合用户体验的——先等每个视频都缓冲够2秒再开始切换,避免播放时卡顿,搭配GSAP的丝滑动画确实能提升质感。我给你拆解一下具体的实现思路和代码示例:
核心逻辑
本质就是监听每个视频的缓冲进度,当所有视频都满足“至少缓冲了2秒内容”的条件后,再隐藏加载spinner,启动你的GSAP切换动画。这里主要用到HTML5 video元素的buffered属性来获取已缓冲的时间范围。
分步实现
1. 先搭好基础HTML结构
把视频容器、加载提示spinner都准备好,记得给video标签加上preload="auto",让浏览器主动预加载内容:
<div class="spinner">⏳ 加载中...</div> <div class="video-grid"> <video src="video-1.mp4" preload="auto" muted playsinline></video> <video src="video-2.mp4" preload="auto" muted playsinline></video> <!-- 这里可以放N个视频 --> </div>
(加muted和playsinline是为了兼容移动端自动播放的限制)
2. 编写JavaScript逻辑
我们需要跟踪每个视频的就绪状态,直到全部达标再触发后续动作:
// 获取DOM元素 const spinner = document.querySelector('.spinner'); const videos = Array.from(document.querySelectorAll('.video-grid video')); // 用数组记录每个视频是否已满足缓冲要求 const isVideoReady = new Array(videos.length).fill(false); // 检查单个视频是否符合条件:缓冲≥2秒,或视频本身时长不足2秒时缓冲完整个视频 function checkVideoBuffer(video) { // 先确保视频元数据已加载(能拿到时长) if (video.duration === 0) return false; // 视频总时长≤2秒的情况,缓冲完就达标 if (video.duration <= 2) { return video.buffered.end(0) >= video.duration; } // 常规情况:检查是否缓冲了至少2秒 return video.buffered.end(0) >= 2; } // 检查所有视频是否都就绪 function allVideosReady() { return isVideoReady.every(status => status); } // 单个视频的缓冲进度监听函数 function setupVideoListener(index) { return function() { const video = videos[index]; if (checkVideoBuffer(video)) { // 标记该视频就绪,移除监听避免重复触发 isVideoReady[index] = true; video.removeEventListener('progress', this); // 检查所有视频是否都达标了 if (allVideosReady()) { // 隐藏spinner,启动GSAP动画 gsap.to(spinner, { opacity: 0, display: 'none', duration: 0.3 }); initGSAPVideoSwitches(); } } }; } // 初始化所有视频的监听 videos.forEach((video, index) => { // 主动触发视频加载 video.load(); // 监听缓冲进度变化 video.addEventListener('progress', setupVideoListener(index)); // 处理视频已缓存的情况:元数据加载完成后直接检查 video.addEventListener('loadedmetadata', () => { if (checkVideoBuffer(video)) { isVideoReady[index] = true; if (allVideosReady()) { gsap.to(spinner, { opacity: 0, display: 'none', duration: 0.3 }); initGSAPVideoSwitches(); } } }); }); // 这里写你的GSAP视频切换动画逻辑 function initGSAPVideoSwitches() { // 举个例子:循环切换视频,淡入淡出效果 const switchTimeline = gsap.timeline({ repeat: -1 }); // 先设置第一个视频显示,其他隐藏 videos.forEach((video, idx) => { gsap.set(video, { opacity: idx === 0 ? 1 : 0 }); }); // 添加切换动画 videos.forEach((video, index) => { if (index < videos.length - 1) { switchTimeline.to(video, { opacity: 0, duration: 0.6 }, `+=3`) .to(videos[index+1], { opacity: 1, duration: 0.6 }, `-=0.6`); } else { // 最后一个视频切换回第一个 switchTimeline.to(video, { opacity: 0, duration: 0.6 }, `+=3`) .to(videos[0], { opacity: 1, duration: 0.6 }, `-=0.6`); } }); }
3. 额外优化点
- 移动端浏览器可能会限制自动预加载,你可以考虑在用户点击某个按钮后再触发视频加载逻辑,避免浪费用户流量
- 给spinner加个CSS动画,比如旋转效果,让加载状态更直观
- 如果视频是动态生成的(比如从接口获取后添加到页面),记得给新创建的video元素绑定同样的缓冲监听事件
内容来源于stack exchange
相关产品推荐
相关产品推荐

