Swiper基于视频播放暂停事件控制自动播放启停的实现问题
Swiper轮播混合视频/图片自动播放控制方案
需求说明
在开启autoplay自动播放属性、开启循环模式的Swiper容器内混合放置视频、图片两类元素,需实现以下交互:
- 幻灯片内的视频处于播放状态时,停止Swiper自动轮播
- 视频暂停或播放结束时,重新启动Swiper自动轮播
- 轮播切换到下一张幻灯片时,当前幻灯片内的视频从头开始自动播放
原有代码失效原因
原有实现仅第一轮轮播生效,第二轮循环后控制失效,核心问题有3个:
- 开启
loop: true时Swiper会自动复制首尾幻灯片生成循环结构,原有逻辑仅给初始加载的第一个视频元素绑定事件,动态复制生成的视频元素没有绑定对应监听事件 - 未监听Swiper的幻灯片切换事件,无法实现切页时重置视频状态、自动播放当前页视频的逻辑
- 仅绑定了视频播放、播放结束事件,遗漏了视频暂停事件的处理,且部分Swiper版本API调用方式不匹配
正确实现代码
$(function () { var mySwiper = new Swiper('.swiper-container', { direction: 'horizontal', loop: true, pagination: '.swiper-pagination', nextButton: '.swiper-button-next', prevButton: '.swiper-button-prev', autoplay: 3000, // 避免用户操作后永久停止自动播放 autoplayDisableOnInteraction: false, // 初始化完成回调 onInit: function(swiper) { bindVideoEvent(swiper); // 初始页如果是视频则自动播放 playCurrentSlideVideo(swiper); }, // 幻灯片切换完成回调 onSlideChangeEnd: function(swiper) { playCurrentSlideVideo(swiper); } }); // 绑定视频播放/暂停/结束事件 function bindVideoEvent(swiper) { var allVideos = swiper.$el.find('.video'); allVideos.off('play pause ended').on('play', function() { // 仅当前激活页的视频播放时停止自动轮播,避免后台视频误触发 if($(this).parents('.swiper-slide').is('.swiper-slide-active')) { swiper.stopAutoplay(); } }).on('pause ended', function() { // 视频暂停/播放结束时重启自动轮播 swiper.startAutoplay(); }); } // 播放当前激活幻灯片的视频,暂停其他所有视频并重置进度 function playCurrentSlideVideo(swiper) { swiper.$el.find('.video').each(function() { this.pause(); this.currentTime = 0; }); var activeVideo = swiper.slides.eq(swiper.activeIndex).find('.video')[0]; if(activeVideo) { // 默认静音适配浏览器自动播放策略,需要有声可在用户交互后取消静音 activeVideo.muted = true; activeVideo.play(); } } });
注意事项
- 上述代码适配Swiper3.x版本API,如果使用Swiper4+版本,需将
stopAutoplay/startAutoplay替换为autoplay.stop()/autoplay.start(),回调函数对应调整为新版事件监听写法即可 - 逻辑兼容loop循环模式下动态生成的幻灯片元素,不会出现多轮循环后事件失效的问题
- 如果需要有声播放,需增加首次用户交互后取消视频静音的逻辑,否则会被浏览器默认自动播放策略拦截
内容的提问来源于stack exchange,提问作者Thajudeen K
相关产品推荐
相关产品推荐

