swiper 实现 带video的banner
2020-11-12 本文已影响0人
八妹sss
遇到的问题:
1、swiper复制的节点点击事件失效问题
2、多个视频同时播放的问题
3、安卓手机上视频播放后轮播卡顿的问题
解决问题2问题3的思路:
页面展示用图片展示,点击播放视频时才显示video元素,当前换到下一个时,暂停上一个并隐藏video元素
解决方法见代码
<template>
<div class="main">
<div v-if="bannerList.length" class="banner-wrapper">
<swiper :class="{single: bannerList.length === 1}" v-if='bannerList.length > 1' :options="swiperOption">
<swiper-slide v-for='(banner, index) of bannerList' :key='"banner" + index'>
<div class='banner-content'>
<video
v-if="banner.bannerVideo"
:ref="`publicVideo${index}`"
style="width: 100%; height: 100%; object-fit: fill"
controls="controls"
webkit-playsinline
playsinline
x5-playsinline
:poster="banner.bannerImg"
:src='banner.bannerVideo'>
<source :src="banner.bannerVideo" type="video/mp4;"/>
</video>
<div v-if="banner.bannerVideo" class="play"></div>
<img
class='banner-img'
:src="banner.bannerImg">
<div class='banner-name'>{{banner.bannerName}}</div>
</div>
</swiper-slide>
</swiper>
<div class='banner-content' v-else>
<video
v-if="bannerList[0].type"
:ref="`publicVideo${index}`"
style="width: 100%; height: 100%; object-fit: fill"
controls="controls"
webkit-playsinline
playsinline
x5-playsinline
:poster="bannerList[0].bannerImg"
:src='bannerList[0].bannerImg'>
<source :src="bannerList[0].bannerImg" type="video/mp4;"/>
</video>
<img
v-else
class='banner-img'
:src="bannerList[0].bannerImg">
<div v-if="bannerList[0].type" class="play"></div>
<div class='banner-name'>{{bannerList[0].bannerName}}</div>
</div>
</div>
<div class="mt-title">关于公司</div>
<ul class="info-list">
<li @click="onJump('companyIntroduce')" class="info-item">
<div class="bg-right"></div>
<div class="bg-tag">About Us</div>
<div class="cont">
<p class="title"></p>
<p class="learn-more"><span>了解详情</span><span class="icon-arrow"></span></p>
</div>
</li>
<li @click="onJump('listedProducts')" class="info-item">
<div class="bg-right"></div>
<div class="bg-tag">Product</div>
<div class="cont">
<p class="title"></p>
<p class="learn-more"><span>了解详情</span><span class="icon-arrow"></span></p>
</div>
</li>
<li @click="onJump('mainResearch')" class="info-item">
<div class="bg-right"></div>
<div class="bg-tag">Develop</div>
<div class="cont">
<p class="title"></p>
<p class="learn-more"><span>了解详情</span><span class="icon-arrow"></span></p>
</div>
</li>
</ul>
<div class="contact-us">
<div @click="onJump('contactWe')" class="cont">
<p class="icon-contact"><img src="" alt=""></p>
<p class="text">联系我们</p>
</div>
</div>
</div>
</template>
<script>
import { swiper, swiperSlide } from 'vue-awesome-swiper'
import 'swiper/dist/css/swiper.css'
let vm = null
export default {
components: {
swiper,
swiperSlide
},
data () {
return {
bannerList: [],
swiperOption: {
watchSlidesProgress: true,
slidesPerView: 'auto',
spaceBetween: 8,
centeredSlides: true,
observer: true,
observeParents: true,
loop: true,
loopedSlides: 5,
on: {
// 解决复制的节点无法点击的问题
click () {
const realIndex = this.realIndex
if (vm.bannerList[realIndex]) {
// 视频播放
if (vm.bannerList[realIndex].bannerVideo) {
vm.showControls()
// banner 跳转
} else if (vm.bannerList[realIndex].jumpLink) {
location.href = vm.bannerList[realIndex].jumpLink
}
}
},
// 控制slid缩放
slideChangeTransitionStart: function () {
vm.watchPlay() // 隐藏所有视频元素
vm.pauseAll(this.realIndex) // 暂停播放的视频
}
}
}
}
},
methods: {
// 获取banner
fetchBanner () {
this.$_load.show()
let url = `${this.SERVICE_PORTAL}/${localStorage.getItem('appid')}/banner`
this.$get(url).then(res => {
this.$_load.hide()
if (res.code === 200) {
let data = res.data
if (data) {
this.bannerList = data
if (this.bannerList.length > 2) {
this.swiperOption.loop = true
this.swiperOption.loopedSlides = 5
} else {
this.swiperOption.loop = false
this.swiperOption.loopedSlides = 0
}
this.$nextTick(() => {
this.watchPlay()
})
}
}
}).catch(() => {
this.$_load.hide()
})
},
// 点击蒙层播放视频
showControls () {
this.watchPlay()
let dom = document.querySelector('.swiper-slide-active video')
if (dom) {
dom.style.display = 'block'
document.querySelector('.swiper-slide-active .banner-img').style.display = 'none'
document.querySelector('.swiper-slide-active .play').style.display = 'none'
dom.controls = false
dom.play()
setTimeout(() => {
dom.controls = true
}, 0)
}
},
// 监听所有视频的播放事件并暂停
watchPlay () {
// 隐藏所有的video标签
let videoAllDom = document.querySelectorAll('video')
let playAllDom = document.querySelectorAll('.play')
let imgAllDom = document.querySelectorAll('.banner-img')
let self = this
for (let i = 0; i < imgAllDom.length; i++) {
imgAllDom[i].style.display = 'block'
}
for (let i = 0; i < videoAllDom.length; i++) {
(function () {
var p = i
videoAllDom[p].style.display = 'none'
playAllDom[p].style.display = 'block'
videoAllDom[p].addEventListener('play', () => {
self.pauseAll(p)
})
})()
}
},
// 暂停所有视频
pauseAll (index) {
let videoAllDom = document.querySelectorAll('video')
for (var j = videoAllDom.length - 1; j >= 0; j--) {
if (j !== index) videoAllDom[j].pause()
}
},
onJump (routeName) {
if (routeName === 'listedProducts') {
this.linkTo(routeName, {}, { type: 'al' })
} else {
this.linkTo(routeName)
}
}
},
created () {
vm = this
this.fetchBanner()
}
}
</script>
<style lang="stylus" scoped>
.main
width 100%
max-width 750px
margin 0 auto
min-height 100vh
background #fff
padding-bottom 40px
box-sizing border-box
.banner-wrapper
width 100%
padding 18px 0px 16px
box-sizing border-box
// 单张时
.single
>>> .swiper-container
height auto
>>> .swiper-slide
width 100%
>>> .swiper-container
height 185px
>>> .swiper-slide
width 91%
&.swiper-slide-active
opacity 1 !important
&.swiper-slide-next
&.swiper-slide-prev
opacity 0.8 !important
.banner-content
height 100%
position relative
border-radius 4px
overflow hidden
font-size 0
video
width 100%
height 100%
display none
.banner-img
display block
width 100%
height 100%
.play
width 100%
height 100%
background rgba(0, 0, 0, 0.06) url('~assets/img/home_ic_play@3x.png') no-repeat center / 45px
border-radius 4px
position absolute
top 50%
left 50%
transform translate(-50%, -50%)
z-index 1
.banner-name
position absolute
bottom 6px
left 0
right 0
background url('~assets/img/ic_biaoti@3x.png') no-repeat left center/ 292px 29px
color #fff
padding 0 36px 0 10px
font-size 15px
font-weight 500
line-height 21px
noWrap()
z-index 2
.mt-title
width 100%
padding 0 16px
line-height 22px
font-size 18px
font-family 'PingFangSC-Semibold', 'PingFang SC'
font-weight 700
color #333333
margin-top 13px
.info-list
width 100%
padding 0 16px
margin-top 13px
.info-item
width 100%
height 96px
border-radius 6px
box-shadow 0px 0px 6px 0px rgba(0, 0, 0, 0.08)
position relative
& + .info-item
margin-top 20px
.bg-right
width 90px
height 90px
position absolute
right 25px
top 50%
transform translate(0, -50%)
.bg-tag
font-size 32px
font-family 'PingFangSC-Semibold', 'PingFang SC'
font-weight 700
color #EAEAEA
position absolute
top 20px
left 35px
z-index 1
.cont
width 100%
height 100%
padding 30px 156px 0 34px
box-sizing border-box
position absolute
top 50%
left 50%
transform translate(-50%, -50%)
z-index 2
.learn-more
display flex
align-items center
font-size 14px
font-family 'PingFangSC-Regular', 'PingFang SC'
font-weight 400
color #333333
line-height 18px
margin-top 5px
.icon-arrow
display inline-block
width 11px
height 11px
background url('~assets/img/home_ic_more@3x.png') no-repeat center / 100%
margin-left 3px
&:nth-of-type(1)
background #fff url('~assets/img/gongsijieshao@3x.png') no-repeat left center / 114px 96px
.bg-right
background url('~assets/img/home_ic_gongsijieshao@3x.png') no-repeat center / 90px
.cont
.title
width 82px
height 20px
background url('~assets/img/tex_gongsi@3x.png') no-repeat center / 100%
&:nth-of-type(2)
background #fff url('~assets/img/chanpin@3x.png') no-repeat left center / 114px 96px
.bg-right
background url('~assets/img/home_ic_chanpin@3x.png') no-repeat center / 90px
.bg-tag
top 22px
.cont
padding 32px
.title
width 102px
height 20px
background url('~assets/img/tex_chanpin@3x.png') no-repeat center / 100%
&:nth-of-type(3)
background #fff url('~assets/img/zaiyanchanpin@3x.png') no-repeat left center / 114px 96px
.bg-right
background url('~assets/img/home_ic_zaiyanchanpin@3x.png') no-repeat center / 90px
.bg-tag
top 23px
.cont
padding-top 33px
.title
width 123px
height 20px
background url('~assets/img/tex_zaiyanchanpin@3x.png') no-repeat center / 100%
.contact-us
display flex
justify-content flex-end
padding-right 15px
margin-top 28px
.cont
display flex
flex-direction column
align-items center
.icon-contact
width 54px
height 54px
background url('~assets/img/home_ic_lianxi@3x.png') no-repeat center / 100%
.text
line-height 16px
font-size 12px
font-family 'PingFangSC-Medium', 'PingFang SC'
font-weight 500
color #333333
</style>