赵三少
赵三少
  • 发布:2021-01-13 20:00
  • 更新:2023-02-02 19:48
  • 阅读:1511

【报Bug】uniapp nvue 页面 使用list组件 pagingEnabled = true @scroll contentOffset.y 不准确

分类:uni-app

产品分类: uniapp/App

PC开发环境操作系统: Windows

PC开发环境操作系统版本号: WINDOWS 7

HBuilderX类型: 正式

HBuilderX版本号: 3.0.5

手机系统: iOS

手机系统版本号: iOS 11.4

手机厂商: 苹果

手机机型: iphone 6

页面类型: nvue

打包方式: 云端

项目创建方式: HBuilderX

示例代码:
<template>  
    <div class="width-fall" :style="'height:'+windowHeight+'px;'">  
        <list class="width-fall" @touchstart="touchstart" @touchend="touchend" :show-scrollbar="false" :style="'height:'+windowHeight+'px'"  
         :pagingEnabled="true" alwaysScrollableVertical="true" :offset-accuracy="windowHeight" @scroll="switchVideo">  
            <refresh @pullingdown='onpullingdown' @refresh="onrefresh" :display=" refreshing ? 'show' : 'hide' " :style="'width: '+windowWidth+'px;padding-top:100px'">  
                <loading-indicator></loading-indicator>  
            </refresh>  
            <!-- @appear="appear" @disappear="disappear" :data-index="index"  :data-item="item" -->  
            <cell class="width-fall" :style="'height:'+windowHeight+'px;position: relative;'" :key="item.video_id" v-for="(item,index) in lists">  
                <video @click="clickVideo(index,'video_'+item.video_id)" :id="'video_'+item.video_id" :src="item.video_url" preload="auto"  
                 :show-play-btn="false" :show-center-play-btn="false" :controls="false" :show-loading="false" :loop="true"  
                 :enable-progress-gesture="false" :style="{ height: windowHeight+'px', width: windowWidth+'px' }" :autoplay="cur_index===index" :muted="cur_index!==index"  
                 objectFit="fill" play-btn-position="center" :poster="item.poster_url"></video>  
                <image :style="'width: '+(windowWidth/5)+'px;height: '+(windowWidth/5)+'px;position: absolute;left:'+(windowWidth/2-(windowWidth/5/2))+'px;top:'+(windowHeight/2-(windowWidth/5/2))+'px;opacity:.3'"  
                 v-if="!item.play && cur_index===index" :src="'../../static/play_1.png'"></image>  
                <cover-view class="cover-view-left">  
                    <text class="view-left-text">@{{ item.nickname }}</text>  
                    <view class="view-left-text-content">  
                        <text class="text-content-text">{{ item.video_describe }}</text>  
                    </view>  
                </cover-view>  
                <cover-view class="cover-view-right">  
                    <cover-image :src="item.cover_url" class="avater img" @click.stop="tapAvater"></cover-image>  
                    <text class="right-follow">+</text>  
                    <cover-image :src="item.is_dianzan ? '/static/img/axc.png' : '/static/img/bed.png'" class="img-left" @click.stop="tapLove"></cover-image>  
                    <text class="right-text">{{ item.dianzan }}</text>  
                    <cover-image src="/static/img/ay2.png" style="height: 80rpx;" class="img-left" @click.stop="tapMsg"></cover-image>  
                    <text class="right-text">{{ item.pinglun }}</text>  
                    <cover-image src="/static/img/b6p.png" style="height: 76rpx;" class="img-left" @click.stop="tapShare"></cover-image>  
                    <text class="right-text">{{ item.zhuanfa }}</text>  
                    <div class="musicIcon img">  
                        <cover-image src="/static/changpian.png" class="img"></cover-image>  
                    </div>  
                </cover-view>  
            </cell>  
        </list>  
        <div v-if="updateVideo" :style="'height:'+windowHeight+'px;width: '+windowWidth+'px;background-color:rgba(0,0,0,.6 );position: fixed;'" @click.stop="" @mousewheel.stop.prevent @touchmove.prevent=""></div>  
        <myTabbar/>  
    </div>  
</template>  
<script>  
    import myTabbar from '@/components/tabbar/tabbar.vue'  
    export default {  
        components: {  
            myTabbar  
        },  
        data() {  
            return {  
                timeOut:'',  
                updateVideo: false,  
                loadEnd: false,  
                videoCtx: [], //视频对象  
                page: 1,  
                pageSize: 8,  
                refreshing: false,  
                refreshText: '↓ Pull To Refresh',  
                contentOffset: 0,  
                cur_index: 0,  
                windowHeight: 0,  
                windowWidth: 0,  
                lists: []  
            }  
        },  
        onLoad() {  
            uni.getSystemInfo({  
                success: (res) => {  
                    this.windowWidth = res.windowWidth;  
                    this.windowHeight = res.windowHeight;  
                }  
            })  
            this.getViewList();  
        },  
        methods: {  
            //控制滑动频率  
            touchstart(e) {  
                /*this.updateVideo = true;*/  
            },  
            touchend(e) {  
                /*clearTimeout(this.timeOut);  
                this.timeOut = setTimeout(()=>{  
                    this.updateVideo = false;  
                },300)*/  
            },  
            getViewList() {  
                let list = this.lists;  
                let videoCtx = this.videoCtx;  
                for (let i = 1; i <= 8; i++) {  
                    list.push({  
                        video_id: i,  
                        nickname: "阿拉蕾",  
                        video_describe: "视频文案视频文案视频文案视频文案视频文案",  
                        cover_url: "https://wx.qlogo.cn/mmopen/vi_32/OyF68EibmjutPT9YhGQyndCRlAnHuWLZCxf2a8tCgIqudUZzhnI7GOwoKMc28onTCicTe29cxviaaq2hmVoVm5Npw/132",  
                        video_url: "../../static/video/video_" + i + ".mp4",  
                        poster_url: "https://wx.qlogo.cn/mmopen/vi_32/OyF68EibmjutPT9YhGQyndCRlAnHuWLZCxf2a8tCgIqudUZzhnI7GOwoKMc28onTCicTe29cxviaaq2hmVoVm5Npw/132",  
                        dianzan: "喜欢",  
                        is_dianzan: true,  
                        play: false,  
                        pinglun: "评论",  
                        zhuanfa: "分享",  
                        firstLoad: true  
                    })  
                    videoCtx.push(uni.createVideoContext('video_' + i, this))  
                }  
                if (!this.loadEnd) {  
                    this.loadEnd = true;  
                    list[0].play = true;  
                }  
                this.lists = list;  
                this.videoCtx = videoCtx;  

            },  
            clickVideo(index, id) {  
                if (this.lists[index].play) {  
                    this.videoCtx[index].pause();  
                } else {  
                    this.videoCtx[index].play();  
                }  
                this.lists[index].play = !this.lists[index].play;  
            },  
            /* 触发滚动 */  
            switchVideo(event) {  
                let cur_index = this.cur_index;  
                this.videoCtx[cur_index].pause();  
                this.lists[cur_index].play = true;  
                if (event.contentOffset.y < this.contentOffset) {  
                    cur_index++;  
                } else {  
                    cur_index--;  
                }  
                this.videoCtx[cur_index].play();  
                this.lists[cur_index].play = false;  
                //重新记录位置  
                this.cur_index = cur_index;  
                this.contentOffset = event.contentOffset.y;  
                this.clickVideo(this.cur_index)  
                console.log(this.contentOffset)  
            },  
            //下拉刷新监听  
            onpullingdown(e) {  
                if (this.refreshing) return;  
                if (Math.abs(e.pullingDistance) > Math.abs(e.viewHeight)) {  
                    this.refreshText = '↑ Pull To Refresh'  
                } else {}  
            },  
            onrefresh(e) {  
                if (this.refreshing) return;  
                this.refreshing = true;  
                setTimeout(() => {  
                    this.refreshing = false;  
                    console.log('下拉刷新了视频');  
                    this.refreshText = '↓ Pull To Refresh'  
                }, 1000)  
            }  

        }  
    }  
</script>  

<style lang="scss">  
    .cover-view-left {  
        position: absolute;  
        margin-left: 20rpx;  
        width: 580rpx;  
        bottom: 100rpx;  
        z-index: 9999;  
        font-size: 14px;  
        color: #ffffff;  
        //#ifndef APP-PLUS-NVUE  
        bottom: 30rpx;  
        //#endif  
    }  

    .left-text {  
        font-size: 14px;  
        color: #ffffff;  
    }  

    .cover-view-right {  
        position: absolute;  
        bottom: 40px;  
        right: 30rpx;  
        z-index: 9999;  
        text-align: center;  
        //#ifndef APP-PLUS-NVUE  
        bottom: 0rpx;  
        //#endif  
    }  
    .avater {  
        border-radius: 50%;  
        border-width: 2px;  
        border-style: solid;  
        border-color: #ffffff;  
    }  

    .img {  
        height: 90rpx;  
        width: 90rpx;  
        margin-bottom: 50rpx;  
    }  

    .img-left {  
        width: 80rpx;  
        height: 66rpx;  
        padding-left: 4px;  
    }  

    .right-follow {  
        position: absolute;  
        z-index: 100;  
        top: 75rpx;  
        left: 28rpx;  
        color: #ffffff;  
        font-size: 16px;  
        width: 34rpx;  
        height: 34rpx;  
        background-color: #f12f5b;  
        text-align: center;  
        line-height: 34rpx;  
        border-radius: 17rpx;  
    }  

    .right-text {  
        color: #ffffff;  
        font-size: 11px;  
        text-align: center;  
        margin-bottom: 40rpx;  
    }  

    .musicIcon {  
        margin-top: 40rpx;  
        animation:  3s  normal;  
        animation-name: rotating;  
        animation-duration: 3s;   
        animation-timing-function:linear;  
        animation-iteration-count: infinite;  
    }  

    @keyframes rotating {  
        from {  
            transform: rotate(0);  
        }  

        to {  
            transform: rotate(360deg);  
        }  
    }  

    .view-left-text-content {  
        flex: 1;  
    }  

    .view-left-text {  
        color: #ffffff;  
        font-size: 18px;  
        margin-bottom: 10rpx;  
        font-weight: bold;  
    }  

    .text-content-text {  
        color: #ffffff;  
        font-size: 16px;  
        line-height: 50rpx;  
        height: 100rpx;  
        overflow: hidden;  
    }  
</style>  

操作步骤:

运行代码 快速滑动视频 就可以看出来 scroll打印的不对

预期结果:

应该每次都 会出现屏幕高度的整倍数 不应该出现小数

实际结果:

会出现小数点、出现小数点就意味触发监听的时间不正确。

bug描述:

uniapp nvue 页面 使用list组件 @scroll pagingEnabled = true 快速滑动时(测试约频率<700毫秒每次的时候)会出现 contentOffset.y 不准确
滑动速度大于700毫秒每次的时候基本就不会出这个问题。
没有打包 真机运行的时候就出现了这个问题

2021-01-13 20:00 负责人:无 分享
已邀请:
赵三少

赵三少 (作者) - 996程序猿

自己顶,主要为实现仿抖音效果。swiper不知道有没有性能问题,虽然是使用的Nvue.

风云杭州

风云杭州

关注,过一阵也要做仿抖音效果

熟悉的陌生人

熟悉的陌生人

swiper不行, 它不能斜滑, 只能正上正下,或者正左正右的滑

该问题目前已经被锁定, 无法添加新回复