最近公司要求做一个项目,要求:视频跟图片一起轮播,当有视频时,要等视频播放完成再继续轮播下一个图片或视频,当没有图片且只有一个视频时,要让它播放完成继续轮播当前视频,具体做法如下:
1.第一步:我的轮播视频是引用了bootstrap3的轮播组件,进入官网bootstrap引用css和两个脚本,接着就可以把轮播的案列引进页面,因为我没有后端的数据,自己写了个数组文件(这些文件你可以在本地自己根据路径引入,我是写在了img里面):
var ele = [
'img/video.mp4',
'img/date.png',
'img/video.mp4',
'img/video.mp4',
'img/two.jpg',
'img/date.png',
'img/video01.mp4',
]
这个数组数据,我用了jq动态的把它拼接到了html里面,html里面代码如下:
2.上面的html代码已经完成,接下来我们要用jq逻辑判断,我们拿到文件数组后,我们怎么知道当前轮播的视频还是图片呢,好了,现在我们可以写两个方法判断,一个是截取到链接后面的后缀名(已待第二个方法判断),一个是根据第一个方法判断是视频或是图片,两个方法实现如下:
//第一个方法
//截取链接的最后一个后缀格式
function getExt(name) {
const parts = name.split('.')
return parts[parts.length - 1]
}
//第二个方法
//判断文件格式类型
function mediaType(name) {
const ext = this.getExt(name)
// console.log('this',this)
if (['jpg', 'png'].includes(ext)) {
return 'image'
} else if (['mkv', 'mp4', 'ogg', 'avi'].includes(ext)) {
return 'video'
} else {
return 'unknown'
}
}
3.好了现在有了上面的两种判断方法,我们就可以动态的拼接dome元素了,如果不加判断你怎么动态的知道当前数组里面的当前链接是img或是video呢,对吧,废话不多说,拼接dome代码如下:
//追加dome元素
function addDoem() {
var imgList = ''
// console.log('items',ele)
//先动态拼接dome元素,判断图片或是视频
for (let i = 0; i < ele.length; i++) {
if (mediaType(ele[i]) == 'image') {
imgList += " "
imgList += "
";
imgList += ""
} else {
imgList += " "
imgList += ""
imgList += ""
}
}
//把判断出来的dome元素分别追加到bootstrap下面的carousel-inner容器下
$('.carousel-inner').append(imgList)
// $('.carousel-inner').append(msg)
//追加第一个div的类名追加属性active
$('.carousel-inner').children('div:eq(0)').addClass('active')
//重点:这里得把上面拼接到的dome元素再循环一遍判断,然后追加src属性,这里踩了个坑就是直接在上面追加src
//没有出来效果,因为元素还没有拼接出来,所以这里得再循环ele里面的元素再进行判断
var imge = []
var videAdd = []
var indexs = []
ele.forEach(function (value, index) {
// console.log(value)
if (mediaType(value) == 'image') {
imge.push(value)
} else {
videAdd.push(value)
indexs.push(index)
}
})
//拼接video元素
//判断是否存在一个视频,是的话让它重复轮播
var it_length = $('.item').length
//如果ele的length等于1逻辑且类型等于video
if(it_length == 1 && mediaType(ele[0]) == 'video') {
var imgList = ''
if ($('.item').eq(0).is(':has(video)') == true) {
//追加多一个dome元素
imgList += " "
+ ""
+ ""
}
$('.carousel-inner').append(imgList)
ele.push(ele[0])
for (var i = 0; i < ele.length; i++) {
$("video").eq(i).children('source').attr("src", ele[i])
var suffix = getExt(ele[i])
$("video").eq(i).children('source').attr("type", "video/" + suffix)
}
var indexs = [0,1]
for (let i = 0; i < indexs.length; i++) {
$('video').eq(i).attr('id', "myVideo" + indexs[i])
}
console.log('hsphsp',ele)
}else {
for (var i = 0; i < videAdd.length; i++) {
$("video").eq(i).children('source').attr("src", videAdd[i])
var suffix = getExt(videAdd[i])
$("video").eq(i).children('source').attr("type", "video/" + suffix)
}
//拼接img元素
for (let i = 0; i < imge.length; i++) {
$(".imgAdd").eq(i).attr("src", imge[i])
}
//video的id根据下标命名
console.log('indesx', indexs)
for (let i = 0; i < indexs.length; i++) {
$('video').eq(i).attr('id', "myVideo" + indexs[i])
}
}
}
4.到了这里我相信,很多小伙伴们已经可以根据拿到的数组数据判断然后动态拼接图片或是视频了,但我们还有一个问题未解决,就是轮播他默认一秒或两秒轮播一个,那这时你就要判断了,当轮播到的当前下标时,如果是视频就停止轮播,bootstrap的停止轮播时$('.carousel').carousel('pause'),开始轮播时$('.carousel').carousel(),判断当前轮播的下标方法如下:
var carousel = $(".carousel") //轮播容器的dome元素
carousel.on('slide.bs.carousel', function (obj) {
// 当前轮播索引
var idx = $(this).find('.item').index(obj.relatedTarget);
console.log("索引:" + idx);
})
接着我就跟着这个方法判断,如果当前轮播到的是视频就停止播放,当视频播放完成就继续轮播,这里注意了,动态拼接的dome元素你可能用jq获取不到,因为它还没有加载出来,这个时候我们可以设一个定时器去获取就可以解决了,定时器如下:
setTimeout(() => {
//请求你用jq动态拼接的dome元素
},2000)
接着我们就可以判断当前视频播放完成后要做的事件了,首先要拿到当前轮播视频的id,这里我已经在上面动态拼接dome元素的时候,已经判断根据数组下标给video标签名id名了,为了跟下面我们要做的根据轮播到的下标命名一致我给它这样命名:“ myVideo” + idx,这里的idex就是当前轮播的下标,演示代码如下:
setTimeout(() => {
var _slider_show = $('#slidershow');
console.log('$item',$('.item').eq(3).is(':has(video)'))
//这个方法可以查看某元素下是否含有video标签
_slider_show.on('slide.bs.carousel', function (obj) {
// 当前轮播索引
var idx = $(this).find('.item').index(obj.relatedTarget);
console.log("索引:" + idx);
if ($('.item').eq(idx).is(':has(video)') == true) {
// console.log($('.item').eq(idx).find('video'))
//开始
var vid = document.querySelector('video#myVideo' + idx)
//引进video播放结束的判断函数,这里的方法我会在下面再演示出来
currentVideo(vid)
}else{
$('.carousel').carousel();
}
})
}, 1000)
里面有个播放结束的方法currentVideo,方法如下:
//当前判断的video
function currentVideo(vid) {
var _slider_show = $('#slidershow');
vid.addEventListener('play', function () {
console.log("开始播放");
$('.carousel').carousel('pause')
// vid.currentTime = 0;
});
//监听播放结束
vid.addEventListener('ended', function () {
console.log("播放结束");
$('.carousel').carousel();
_slider_show.on('slide.bs.carousel', function (obj) {
// 当前轮播索引
var index = $(this).find('.item').index(obj.relatedTarget);
//根据索引判断,播放结束后,如果再继续轮播到当前的类型是video就重新加载播放
if (mediaType(ele[index]) == "video") {
vid.load()
}
})
})
}
ok,分析结束,有什么不懂的欢迎下方留言
5.整个轮播图的实现完整的代码实现如下:
Title