解决在uniapp项目在 APP端使用video的第一帧黑屏问题、轮播图中左右滑动不了问题、无法操作视频的播放暂停等
(此方式只适配APP端,小程序/H5 需要使用条件编译,再写一套代码)
以下方式在APP端中,会存在首屏加载的时候是黑屏,不能像在H5中会显示第一帧图像
//正常使用video的方式
<video class="video" :src="video" :autoplay="autoplay" :controls="false" object-fit="cover" :enable-progress-gesture="false">
<cover-view class="btn">跳过动画</cover-view>
</video>
以下方式在APP端中,会存在轮播图中左右滑动不了
//正常使用video的方式
<swiper class="swiper" @change="swiperChange">
<swiper-item>
<video class="video" :src="video"></video>
</swiper-item>
<swiper-item>
<image class="image" :src="image"></image>
</swiper-item>
<swiper-item>
<image class="image" :src="image"></image>
</swiper-item>
</swiper>
以下方式在APP端中,可以解决第一帧黑屏,及轮播图中左右滑动不了的问题。
但是使用此方式无法直接操作视频(也就是没办法直接给video添加@play=“play()”事件,从而去操作播放暂停)
//通过v-html插入视图的方式
<swiper class="swiper" @change="swiperChange">
<swiper-item>
<view class="dom-video" v-html="html_video"></view>
</swiper-item>
</swiper>
onLoad(option) {
this.html_video = `<video class="video" id="dom-html-video" src="${this.video}" autoplay></video>`
}
解决方式:需要使用到renderjs
在APP端是没有办法直接使用 document.getElementById 方式的
而 renderjs 给我们提供了获取dom的方式
(注意:renderjs即视图层,与逻辑层是分离的,所以无法直接通过this通信)
什么是逻辑层?视图层?
//html
<template>
<view>
<swiper class="swiper" @change="swiperChange">
<swiper-item>
<view v-html="html_video"></view>
</swiper-item>
</swiper>
</view>
</template>
//逻辑层
<script>
export default {
data() {
return {
str:"逻辑层的数据"
}
},
onLoad(option) {
this.test()
}
methods: {
test(){
console.log(this.str) //逻辑层的数据
},
}
}
</script>
//视图层
<script module="domVideo" lang="renderjs">
export default {
data() {
return {
str:"视图层的数据",
}
},
mounted() {
this.test()
},
methods: {
test(){
console.log(this.str) //视图层的数据
}
}
}
</script>
//样式
<style lang="less" scoped>
.swiper{}
</style>
视图层发送数据,逻辑层接收数据方式:
//逻辑层
<script>
export default {
data() {
return {
str:"逻辑层的数据"
}
},
onLoad(option) {
this.html_video = `<video class="video" id="dom-html-video" src="${this.video}" autoplay></video>`
}
methods: {
//接收视图层传入的数据(绑定方式:方法名称一致)
ended(e){
console.log('ended', e) //打印1
},
}
}
</script>
//视图层
<script module="domVideo" lang="renderjs">
export default {
data() {
return {
str:"视图层的数据"
video:'',
}
},
mounted() {
this.initVideoEvent()
},
methods: {
initVideoEvent(){
setTimeout(() => {
//在视图层可以直接获取dom
let video = document.getElementById(`dom-html-video`)
// 监听视频事件
video.addEventListener('ended', () => {
//发送数据给逻辑层
this.$ownerInstance.callMethod('ended', '1');
})
}, 100)
},
}
}
</script>
//样式
<style lang="less" scoped>
.swiper{}
</style>
逻辑层发送数据,视图层接收数据方式:
//html
<template>
<view>
<swiper class="swiper" @change="swiperChange">
<swiper-item @tap="_videoTap">
//通过视图层的 <script module="domVideo" lang="renderjs"> 绑定
//方式一:直接调用视图层的事件 (不能用this.domVideo.rdPlay)
<view @tap="domVideo.rdPlay" v-html="html_video"></view>
//方法二:通过:change:变量名 调用视图层的事件(要先传入此变量)
<view
:isBofan="isBofan"
:change:isBofan="domVideo.eventHandle"
id="domVideo" v-html="html_video">
</view>
</swiper-item>
</swiper>
</view>
</template>
//逻辑层
<script>
export default {
data() {
return {
str:"逻辑层的数据"
}
},
onLoad(option) {
this.html_video = `<video class="video" id="dom-html-video" src="${this.video}" autoplay></video>`
}
methods: {
//点击 显示隐藏播放按钮
_videoTap(){
this.isBofan = !this.isBofan
},
}
}
</script>
//视图层
<script module="domVideo" lang="renderjs">
export default {
data() {
return {
str:"视图层的数据"
video:'',
}
},
mounted() {
},
methods: {
eventHandle(event){
if(event){
this.rdPlay()
} else {
this.rdPause()
}
},
rdPlay(){
this.video = document.getElementById(`dom-html-video`)
this.video.play()
},
rdPause(){
this.video = document.getElementById(`dom-html-video`)
this.video.pause()
},
}
}
</script>
//样式
<style lang="less" scoped>
.swiper{}
</style>
因篇幅问题不能全部显示,请点此查看更多更全内容