1、要使用scroll-view标签,设置属性:
scroll-y Boolean false 允许纵向滚动
scroll-with-animation Boolean false 在设置滚动条位置时使用动画过渡
scroll-top Number/String 设置竖向滚动条位置
@touchend 触摸后放开触发
@scroll 滚动条事件,可以获取滚动条高度
2、编写逻辑:
重点:
1、封装播放方法
2、渲染视频列表为3个
3、记录组件内部变化的值,在设置新值之前先设置为记录的当前值,防止设置滚动条位置不生效
4、 将设置滚动条高度显示视频的逻辑放入异步队列,实现先加载视频,在设置位置,错开时间,防止视频抖动
// 显示的视频数据固定为3 videoMysql.value为总数据
let videos = ref([])
let videoLeft = ref(0)
let videoRight = ref(videoLeft.value + 3)
videos.value = videoMysql.value.slice(videoLeft.value, videoRight.value)
// 获取元素的高度
let videoHeight = ref(0)
const query = wx.createSelectorQuery();
query.select('#myElement').boundingClientRect((res) => {
videoHeight.value = res.height
}).exec();
// 滚动条显示高度
let scrollTop = ref(0)
// 解决滚动条高度只有一次生效的变量
let oldTop = ref({
scrollTop: 0
})
// 滚动条高度
let scrollHeight = ref(0)
// 滑动屏幕 滚动条事件
const shuaDwon = e => {
// 滚动条高度赋值,用于判断
scrollHeight.value = e.detail.scrollTop
// 记录组件内部变化的值,在设置新值之前先设置为记录的当前值,防止设置滚动条位置不生效
oldTop.value.scrollTop = e.detail.scrollTop
}
// 封装播放函数,屏幕显示什么就播放什么视频
const pause = (indexs) => {
videos.value.forEach((item, index) => {
if (index != indexs) {
// 获取视频元素的API,item.videoSrc为视频标签的id名 pause()暂停 play()播放
uni.createVideoContext(item.videoSrc).pause()
} else {
uni.createVideoContext(item.videoSrc).play()
item.zanShow = true
}
})
}
onLoad(() => {
// 默认播放第一个
pause(0)
})
onMounted(() => {
// 默认播放第一个
pause(0)
})
// 判断视频是否滚动到一半
// 显示的子元素
const touchend = () => {
// 0 videoHeight.value videoHeight.value*2 scrollHeight.value
// 第一层上半层
if (scrollHeight.value > 0 && scrollHeight.value <= videoHeight.value / 2) {
// 判断是否是当前视频列表的第一个
if (videoLeft.value - 1 < 0) {
// 动态加载视频列表,只渲染3个
videoLeft.value = 0
videoRight.value = videoLeft.value + 3
videos.value = videoMysql.value.slice(videoLeft.value, videoRight.value)
// 将设置滚动条高度显示视频的逻辑放入异步队列,实现先加载视频,在设置位置,错开时间,防止视频抖动
setTimeout(() => {
scrollTop.value = oldTop.value.scrollTop
nextTick(() => {
scrollTop.value = 0
})
pause(0)
})
} else {
videoLeft.value = videoLeft.value - 1
videoRight.value = videoLeft.value + 3
videos.value = videoMysql.value.slice(videoLeft.value, videoRight.value)
// 将设置滚动条高度显示视频的逻辑放入异步队列,实现先加载视频,在设置位置,错开时间,防止视频抖动
setTimeout(() => {
scrollTop.value = oldTop.value.scrollTop
nextTick(() => {
scrollTop.value = videoHeight.value
})
pause(1)
})
}
// 下半部
} else if (scrollHeight.value > videoHeight.value / 2 && scrollHeight.value <= videoHeight.value) {
scrollTop.value = oldTop.value.scrollTop
nextTick(() => {
scrollTop.value = videoHeight.value
})
pause(1)
// 第二层的上半部
} else if (scrollHeight.value > videoHeight.value && scrollHeight.value <= (videoHeight.value + videoHeight
.value / 2)) {
scrollTop.value = oldTop.value.scrollTop
nextTick(() => {
scrollTop.value = videoHeight.value
})
pause((1))
// 第二层的下半部
} else if (scrollHeight.value > (videoHeight.value + videoHeight.value / 2) && scrollHeight.value <=
videoHeight.value * 2) {
if (videoLeft.value + 1 > videoMysql.value.length - 3) {
videoLeft.value = videoMysql.value.length - 3
videoRight.value = videoLeft.value + 3
videos.value = videoMysql.value.slice(videoLeft.value, videoRight.value)
// 将设置滚动条高度显示视频的逻辑放入异步队列,实现先加载视频,在设置位置,错开时间,防止视频抖动
setTimeout(() => {
scrollTop.value = oldTop.value.scrollTop
nextTick(() => {
scrollTop.value = videoHeight.value * 2
})
pause((2))
})
} else {
videoLeft.value = videoLeft.value + 1
videoRight.value = videoLeft.value + 3
videos.value = videoMysql.value.slice(videoLeft.value, videoRight.value)
// 将设置滚动条高度显示视频的逻辑放入异步队列,实现先加载视频,在设置位置,错开时间,防止视频抖动
setTimeout(() => {
scrollTop.value = oldTop.value.scrollTop
nextTick(() => {
scrollTop.value = videoHeight.value
})
pause((1))
})
}
}
}