uni-app 新闻/资源模板单列表含video时,全屏播放视频再返回会自动回到列表顶部

uni-app 新闻/资源模板单列表含video时,全屏播放视频再返回会自动回到列表顶部

示例代码:

<video  
    id="myVideo"  
    src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/%E7%AC%AC1%E8%AE%B2%EF%BC%88uni-app%E4%BA%A7%E5%93%81%E4%BB%8B%E7%BB%8D%EF%BC%89-%20DCloud%E5%AE%98%E6%96%B9%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B@20200317.mp4"  
    controls  
></video>

## 操作步骤:
滑动列表一段距离,播放视频->全屏->视频返回

## 预期结果:
列表处于播放视频前所在位置

## 实际结果:
列表返回了顶部

## bug描述:
代码基于uni-app创建的 新闻/资源模板,是要实现图文视频列表的混排,左右滑动切换列表,类似 今日头条 的那种功能,这个模板无疑是很好的,但是使用过程中发现列表中有视频的时候,全屏观看视频,在返回的话列表会自动回到第一条新闻的位置。
如下代码,仅在示例模板的的基础上修改了`news-page.nvue`页面,新增7-13行video模块。

| 开发环境         | 版本号   | 项目创建方式 |
|------------------|----------|--------------|
| Windows          | 10       | HBuilderX    |
| Android          | Android 11 |            |
| 手机厂商         | 手机机型           |
| 小米             | 小米10至尊 miui12.5.21.11.3开发版 |
| HBuilderX        | 3.2.16   |              |
| 页面类型         | vue版本  |
| nvue             | vue2     |              |

## 附件
- [uni-news.zip](//ask.dcloud.net.cn/file/download/file_name-dW5pLW5ld3Muemlw__url-Ly9pbWctY2RuLXRjLmRjbG91ZC5uZXQuY24vdXBsb2Fkcy9xdWVzdGlvbnMvMjAyMTEyMDgvNGExYTBhMzJjZDczN2RjNDEzNzAyMTVkMmE2YWJhY2E=)
- [video.zip](//ask.dcloud.net.cn/file/download/file_name-dmlkZW8uemlw__url-Ly9pbWctY2RuLXRjLmRjbG91ZC5uZXQuY24vdXBsb2Fkcy9xdWVzdGlvbnMvMjAyMTEyMDgvYmE3NDJkYTM0ZTg5YzA1M2M1MjU1MzZmYTNlNTllMjI=)

更多关于uni-app 新闻/资源模板单列表含video时,全屏播放视频再返回会自动回到列表顶部的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

hx3.3.1 alpha已修复

更多关于uni-app 新闻/资源模板单列表含video时,全屏播放视频再返回会自动回到列表顶部的实战教程也可以访问 https://www.itying.com/category-93-b0.html


这个问题是由于全屏播放视频时,页面布局被重新计算导致的。在uni-app的nvue页面中,video组件全屏时会脱离原有布局,返回时页面会重新渲染,导致列表位置丢失。

解决方案如下:

  1. 记录滚动位置:在视频播放前,通过uni.createSelectorQuery()获取当前列表的滚动位置并保存。

  2. 监听视频状态:通过@fullscreenchange事件监听视频全屏状态变化。

  3. 恢复滚动位置:在全屏返回后,使用scrollTo方法将列表滚动到之前记录的位置。

示例代码修改:

// 在data中增加记录变量
data() {
    return {
        scrollTop: 0
    }
},

// 方法中添加
methods: {
    // 记录滚动位置
    recordScrollPosition() {
        uni.createSelectorQuery().select('.list-container').boundingClientRect(res => {
            this.scrollTop = res.scrollTop || 0;
        }).exec();
    },
    
    // 视频全屏变化监听
    handleFullscreenChange(e) {
        if (!e.detail.fullScreen) {
            // 全屏退出后恢复位置
            setTimeout(() => {
                uni.pageScrollTo({
                    scrollTop: this.scrollTop,
                    duration: 0
                });
            }, 100);
        }
    }
}

在template中:

<video 
    @fullscreenchange="handleFullscreenChange"
    @play="recordScrollPosition"
    ...其他属性
></video>
回到顶部