给需要添加视频的slide添加一个特有的类ban_video,来识别需要添加视频的slide。
因为我是动态添加video元素的,所以需要给slide添加视频的第一帧图片,避免加载视频带来的轮播空白问题,同时也为了撑开元素。
把视频相对定位,覆盖在图片的上面,实现图片到视频的无缝连接。
实现视频播放的逻辑:
- 通过判断当前slide(swiper-slide-active)是否包含ban_video类名来实现视频的添加。
- 如果包含,让swiper停止自动滑动mySwiper.stopAutoplay()
- 同时创建video元素,并添加到slide内var videos ='<video src="' + _this.data('video') + '" autoplay="autoplay" muted class="vv" style="display:none;"></video>';_this.append(videos);
- 通过视频的时长是否为数字判断视频是否加载完成,然后显示video
- 通过监听video的ended事件,来实现swiper继续自动轮播以及轮播到下一个slide
- 当不包含ban_video时,把video移除
swiper循环轮播时,onSlideChangeEnd内的回调函数也会同时被执行,这点尤为需要注意。
当视频的尺寸与图片不符时,可以使用object-fit: cover;属性保证视频充满全屏,并且不会变形,但是会有显示不全的问题。与background-size:cover;效果一致。object-fit的详细讲解链接
HTML结构:
<div class="main">
<!--图片轮播-->
<div class="banner">
<div class="swiper-container banner_index">
<div class="swiper-wrapper">
<div class="swiper-slide ban_video" data-video="flash/innovation.mp4">
<img src="upload/in_bnimg01.jpg" alt="">
</div>
<div class="swiper-slide">
<img src="upload/in_bnimg01.jpg" alt="">
</div>
<div class="swiper-slide">
<img src="upload/in_bnimg01.jpg" alt="">
</div>
</div>
<!--<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>-->
<div class="swiper-pagination"></div>
</div>
</div>
</div>
CSS样式:
.banner_index .swiper-slide {
position: relative;
}
.banner_index .swiper-slide img {
width: 100%;
}
.banner_index .swiper-slide video {
position: absolute;
width: 100%;
left: 0px;
top: 50%;
transform: translateY(-50%);
object-fit: cover;
}
JS:
//有loop:true时,11 22 44 33,首先执行的是onSlideChangeEnd
//没有loop:true时,22 44 33,onSlideChangeEnd不会被首先执行
$(document).ready(function() {
var swiperFlag = false;
var mySwiper = new Swiper('.banner_index', {
autoplay: 5000, //可选选项,自动滑动
autoHeight: true,
loop: true,
// pagination : '.banner_index .swiper-pagination',
// prevButton: '.banner_index .swiper-button-prev',
pagination: '.banner_index .swiper-pagination',
paginationClickable: true,
onSlideChangeEnd: function(swiper) {
console.log(swiper.activeIndex);
// console.log(11);
var _this = $('.banner_index .swiper-slide').eq(swiper.activeIndex);
if(!swiperFlag) {
swiperFlag = true;
} else {
videoSelect(_this);
}
}
})
// console.log(22);
videoSelect($('.banner_index .swiper-slide.swiper-slide-active'));
// console.log(33);
function videoSelect(_this) {
var flag = true;
var cc = _this.hasClass('ban_video');
if(cc) {
// console.log(44);
mySwiper.stopAutoplay();
var videos =
'<video src="' + _this.data('video') + '" autoplay="autoplay" muted class="vv" style="display:none;"></video>';
_this.append(videos);
var aaa = setInterval(function() {
if(!isNaN($(".vv").get(0).duration) && flag) {
clearInterval(aaa);
flag = false;
setTimeout(function() {
_this.find('video').css("display", "block");
}, 500)
}
}, 10);
_this.find('video').bind('ended', function() {
mySwiper.slideNext();
mySwiper.startAutoplay();
});
} else {
$('.vv').remove();
}
}
})