diff --git a/pages/index/index.js b/pages/index/index.js index 0dd7a97..631476f 100644 --- a/pages/index/index.js +++ b/pages/index/index.js @@ -63,6 +63,7 @@ Page({ partnerstatus: '', viewedGoods: [], // 已浏览商品ID列表 isInPersonnel: false, // 用户手机号是否在personnel表中 + videoPlaybackStates: {}, // 视频播放状态,键为videoId,值为是否在视口内 // 广告轮播图数据 adCarouselList: [ @@ -604,6 +605,11 @@ Page({ this.loadCategories() this.loadGoods() this.checkPhoneInPersonnel() + + // 页面加载完成后检查视频是否在视口内 + setTimeout(() => { + this.checkVideosInViewport(); + }, 1000); // 计算搜索区域高度 setTimeout(() => { @@ -1157,6 +1163,11 @@ Page({ // soldOutPage 已经在 loadSoldOutData 函数中直接更新 page: this.data.isQueryingSoldOut ? this.data.page : this.data.page + 1, lastDataTimestamp: new Date().getTime() + }, () => { + // 商品数据加载完成后检查视频是否在视口内 + setTimeout(() => { + this.checkVideosInViewport(); + }, 500); }) // 检查过滤后的非广告商品数量,如果不足6个,则自动触发上拉加载更多 @@ -2514,6 +2525,9 @@ Page({ // 动态调整已通过CSS过渡和动态类实现,此处不再需要直接操作DOM // 搜索框始终固定显示,不做隐藏处理 + + // 检查视频是否在视口内并控制播放 + this.checkVideosInViewport(); // 侧边栏按钮显示逻辑 // 下滑时隐藏按钮(除非用户未手动隐藏过且在顶部) @@ -2652,6 +2666,86 @@ Page({ } }, + // 检查视频是否在视口内并控制播放 + checkVideosInViewport: function () { + const filteredGoods = this.data.filteredGoods; + if (!filteredGoods || filteredGoods.length === 0) return; + + const query = wx.createSelectorQuery(); + + // 为每个视频元素创建单独的查询 + filteredGoods.forEach((item, index) => { + if (item.mediaItems && item.mediaItems.length > 0 && item.mediaItems[0].type === 'video') { + query.select(`#video-${item.id}`).boundingClientRect(); + } + }); + + query.exec((res) => { + if (!res) return; + + const viewportHeight = wx.getSystemInfoSync().windowHeight; + const videoPlaybackStates = {}; + const visibleVideos = []; + let videoIndex = 0; + + // 遍历所有商品,收集可见的视频 + filteredGoods.forEach((item, itemIndex) => { + if (!item.mediaItems || !item.mediaItems.length || item.mediaItems[0].type !== 'video') { + return; + } + + // 获取对应的视频矩形 + const videoRect = res[videoIndex]; + videoIndex++; + + if (!videoRect) return; + + const videoId = `video-${item.id}`; + + // 计算视频在视口中的可见比例 + const videoHeight = videoRect.height; + const visibleTop = Math.max(0, videoRect.top); + const visibleBottom = Math.min(viewportHeight, videoRect.bottom); + const visibleHeight = Math.max(0, visibleBottom - visibleTop); + const visibilityRatio = visibleHeight / videoHeight; + + // 检查视频是否在视口内 + const isInViewport = visibilityRatio > 0.25; + + if (isInViewport) { + visibleVideos.push({ videoId, visibilityRatio }); + } + + videoPlaybackStates[videoId] = isInViewport; + }); + + // 按可见比例排序,选择前2个视频播放 + visibleVideos.sort((a, b) => b.visibilityRatio - a.visibilityRatio); + const videosToPlay = visibleVideos.slice(0, 2).map(v => v.videoId); + + // 控制视频播放/暂停 + filteredGoods.forEach((item, itemIndex) => { + if (!item.mediaItems || !item.mediaItems.length || item.mediaItems[0].type !== 'video') { + return; + } + + const videoId = `video-${item.id}`; + const videoContext = wx.createVideoContext(videoId); + + if (videosToPlay.includes(videoId)) { + videoContext.play(); + } else { + videoContext.pause(); + } + }); + + // 更新视频播放状态 + this.setData({ + videoPlaybackStates: videoPlaybackStates + }); + }); + }, + // 图片加载完成事件 onImageLoad(e) { console.log('图片加载完成:', e); diff --git a/pages/index/index.wxml b/pages/index/index.wxml index f83669b..31f4bc9 100644 --- a/pages/index/index.wxml +++ b/pages/index/index.wxml @@ -286,13 +286,14 @@