uniapp-app的视频轮播图

直接使用swiper做图片轮播图是没有问题的,视频轮播图的兼容性仅仅体现在APP上。

我的方法是将nvue页面作为视频的遮罩层,如果直接将视频放到nvue页面,说不定也可以。其实这个兼容性的关键在于video标签在手机上的层级过高,除了nvue,还有其他方法解决。

因为我的这个项目是图片,视频混合的轮播图,所以很多地方要判断,是否为视频,但测试时,第一项就是视频,所以很多地方判断,swiper的current是否为0。

pages/my/person.vue

<view class="person-head">
	<swiper :current="swiperNum" @change="switchItem" circular indicator-dots 
         v-if="isVideo">
	    <!-- v-for循环遍历数组 -->
		<swiper-item v-for="item in list4">
			<image :src="item.url"></image>
		</swiper-item>
	</swiper>
	<view  v-if="!isVideo">
		<video id="myVideo" src="https://cdn.uviewui.com/uview/resources/video.mp4" 
         autoplay="true" style="width: 100%;height: 442rpx;" :controls="false" 
         :enable-progress-gesture="false">
        </video>
	</view>
</view>

//因为nvue层级很高,如果页面很长,能上下滑动。那nvue还是始终定在屏幕上方,
//用@touchend监听手指滑动,获得这个元素距离屏幕顶端的距离,以此让nvue高度变化。
<view class="person-body" @touchend="log" id="demo">
</view>

//<script>
    //在这里定义,因为很多地方都用到了。获取nvue页面
    const subNvue = uni.getSubNVueById('popup'); //获取
	//export default {


list4: [{
	url: 'https://cdn.uviewui.com/uview/swiper/swiper2.png',
	title: '身无彩凤双飞翼,心有灵犀一点通'
	}, {
	url: 'https://cdn.uviewui.com/uview/swiper/swiper3.png',
	title: '谁念西风独自凉,萧萧黄叶闭疏窗,沉思往事立残阳'
	}, {
	url: 'https://cdn.uviewui.com/uview/swiper/swiper1.png',
	title: 'image'
}],
isVideo: true,
swiperNum: 0,


onLoad(e) {

	// 监听事件  ,监听nvue页面传过来的
	uni.$on('getNvue', (direction) => {
			//因为一旦监听这个事件,代表在左右滑动(切换轮播),所以让视频和遮罩层隐藏
            //因为这里只有第一个是视频,实际要根据情况
			this.isVideo = true
			subNvue.hide()
            //根据是左滑,还是右滑,切换轮播图
			if (direction.elePosition == "left") {
				if (this.swiperNum >= this.list4.length - 1) {
					this.swiperNum = 0
				    console.log(this.swiperNum)
				} else {
					this.swiperNum += 1
					console.log(this.swiperNum)
				}

			} else if (direction.elePosition == "right") {
				if (this.swiperNum <= 0) {
					this.swiperNum = this.list4.length - 1
				} else {
					this.swiperNum -= 1
				}
			}

		})
	},
	onUnload() {
		//要在页面关闭的时候, 移除监听事件 ,隐藏遮罩层 
		uni.$off('getNvue');
		subNvue.hide()
	},
	onShow() {
		// 因为这里只有第一条是视频,所以检测swiper的页数是0时, 显示nvue页面
        //要根据实际情况判断
		if (this.swiperNum == 0) {
			subNvue.show() // 显示
		}

		// 因为switchItem事件,是轮播图切换时才会触发,这里考虑到第一个是视频的情况
		this.$nextTick(() => {
			this.switchItem()
			console.log(222)
		})
	},

	methods: {
       //获得元素距离屏幕顶端的距离,计算nvue需要移动的距离,通过setStyle方法移动
       log(e) {
			setTimeout(() => {
				let query = uni.createSelectorQuery().in(this);
				query.select('#demo').boundingClientRect(data => {
					console.log('元素距离顶部的距离' + data.top)
					let top = data.top>=0&&data.top<=212? 0-Math.trunc(212- 
                    data.top):-282
					const subNvue = uni.getSubNVueById('popup'); //获取
					subNvue.setStyle({"top": top+'px'})
				}).exec();
			}, 300)

		},

		//轮播图切换
		switchItem(obj) {
			console.log(obj)
			// 因为测试的数据第一项是视频,所以这里是0
			if (obj == undefined || obj.detail.current == 0) {
				subNvue.show()
				this.isVideo = false
				this.swiperNum = 0 //这个也要改成视频的index
			} else {
				this.isVideo = true
			}
			console.log(this.swiperNum)
  		},
    }


    .person-head {
		height: 500rpx;
		background-color: #000;
	}

 这是person页面轮播图视频部分的遮罩层(这个页面是透明的,可以设置背景色,方便调试)。
 因为直接用swiper轮播视频,两者底层逻辑之间有bug,h5端运行没问题,但真机测试有很多 
 bug,兼容性问题。
    
 bug之一,video的层级太高,导致视频,左右滑动触发不了swiper的切换。
 且video标签检测不到@touchstart,@touchstart等事件,也就判断不了左右滑动。

    
  解决:nvue(只有在手机上nvue才有效果)的层级比video还高,
  用nvue给video做遮罩层,监测在遮罩层上的滑动方向,判断左滑右滑,以此修改轮播图的页数

pages/my/subNVue/video.nvue

<template>
	<view id="popup">
		<view class="mask" @click="log" @touchstart="touchStart" @touchend="touchEnd">
			
		</view>
	</view>
</template>

<script>
	
	export default {
		data() {
			return {
				startTime: 0,
				startPosition: 0,
				endPosition: 0,
			}
		},
		methods: {
			
			// 起点
			touchStart(event) {
				this.startTime = Date.now()
				this.startPosition = event.changedTouches[0].screenX
			},
			// 终点,计算移动距离
			touchEnd(event) {
				
				const endTime = Date.now()
				if (endTime - this.startTime > 2000) {
					return;
				}
				this.endPosition = event.changedTouches[0].screenX
			
				//当移动距离超过10时判断左滑右滑。
				if (Math.abs(this.endPosition - this.startPosition) > 10) {
					this.endPosition = event.changedTouches[0].screenX
					var elePosition = this.endPosition - this.startPosition > 0 ? "right" : "left"
				} else {
					return;
				}
			
                //将左滑还是右滑,传到父页面
				console.log(elePosition)
				uni.$emit('getNvue', {elePosition:elePosition});
			},
		}
	}
</script>

<style scoped lang="scss">
	.mask {
		position: relative;
		width: 750rpx;
		height: 440rpx;
		background: rgba(0,0,0,0);
	}
</style>

pages.json

添加subNVues,id名要和nvue最外层的view标签的id保持一致。

{
	"path": "pages/my/person",
	"style": {
		"navigationBarTitleText": "个人主页",
		"app-plus": {
			"subNVues": [{
				"id": "popup", // 唯一标识  
				"path": "pages/my/subNVue/video", // 页面路径  
				//"type": "popup",  //原生子窗口内置样式,可取值:'popup',弹出 
                //层;"navigationBar",导航栏
					style": {
					"position":"absolute",
					"height": "442rpx",
                   //只能用transparent使nvue页面透明,其他方法会有bug
                   //测试时可以改为其他颜色,方便观察
					"background": "transparent"  
				}
			}],
			"scrollIndicator": "none",
			"bounce": "none",
			"backgroundColor": "#FFFFFF",
			"titleNView": false
		},
		"enablePullDownRefresh": false
	}
},

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值