uni-app,社交应用中,聊天页面下拉onPullDownRefresh获取历史消息,数据合并之后,滚动到下拉之前的位置,页面看不见闪动,完美解决

会有一股神秘感。 提交于 2020-08-17 18:12:40

一般下拉之后,拿到数据合并,会默认展示顶部第一条,模仿其他聊天应用,回到下拉之前位置,如果不做处理,可以看见下拉得到的数据,本方法完美解决

https://ext.dcloud.net.cn/plugin?id=1841 插件市场

有问题可以留言或者加qq445849201讨论,亲测ios和android都没问题

<template>
    <view class="content">
        <view v-if="isOver" class="msg-over">没有更多消息了</view>
        <view class="pull-content" v-for="(item,index) in msgList" :key="index" :class="index % 2 == 0 ? 'msg-right' : ''" :id="'msg'+item.id">
            <view class="absolute-view" v-show="showIndex>index?'show-index':''"></view>
            <view class="img-box" v-if="item.type == 'img'">
                {{item.id}}<image  class="logo" src="/static/logo.png"></image>
            </view>
            <view v-else class="left-msg">
                {{item.id}}{{item.content}}
            </view>
        </view>
    </view>
</template>












<script>
    export default {
        data() {
            return {
                title: 'Hello',
                msgList:[],
                listPage:0,
                showIndex:-1,
                isOver:false
            }
        },
        onLoad() {
            let _this = this;
            _this.addList();  //产生十条消息
        },
        methods: {
            addList(){
                let _this = this;
                let type = null;
                for(let i = 0; i <10;i++){
                    if(i % 3 == 1){            //消息列表为图片,增加图片消息,增加页面视觉辨识,如果不做处理,在滚动到下拉之前位置时,尤其在低端机上,是可以看见页面图片闪一下
                        type = 'img'           //文字消息不是很闪
                    }else{
                        type = 'msg'           //消息列表为文字消息 ,view循环渲染中判断
                    }
                    let msgObj={               //一条消息对象
                        id:_this.listPage * 10 +i,
                        content:'你有一条新的消息,请注意查收',
                        type:type
                    }
                    _this.msgList.unshift(msgObj);  //插入列表
                }
                if(_this.listPage == 0){            //首次滚动到底部
                    _this.$nextTick(function() {
                        uni.pageScrollTo({
                            scrollTop: 99999,
                            duration: 0
                        });
                    });
                    return;
                }
                if(_this.listPage>3){               //模拟消息取完了,拿出来40条消息
                    _this.isOver = true;             // 标记已无更多消息
                    _this.endOver();                 // 设置禁用下拉加载
                    return;
                }
                //最关键一步,在数据插入列表,渲染之后,没有滚动到下拉之前位置时,采用相对定位,设置同背景色遮罩层盖住消息
                //设置为9意思是,每次拿十条数据,遮住前十条,用数组循环下标判断从0开始,初始化为-1
                _this.showIndex = 9;                
                let scrollMsg = _this.msgList[9];  //数据合并之后,获取10条消息的元素
                _this.$nextTick(function() {
                    let view = uni.createSelectorQuery().select('#msg'+scrollMsg.id);
                    view.boundingClientRect(res => {
                        console.log('#msg'+scrollMsg.id+'距离顶部'+res.top); //获取10条消息的元素距顶部的距离,这就是需要滚动的距离
                        uni.pageScrollTo({         //回到下拉之前,多展示一条消息
                            scrollTop: res.top,
                            duration: 0
                        });
                        _this.showIndex = -1;      //去掉遮罩层
                        uni.stopPullDownRefresh(); //结束下拉加载
                    }).exec();
                });
            },
            endOver(){  //设置禁用下拉加载
                const pages = getCurrentPages();  
                const page = pages[pages.length - 1];  
                const currentWebview = page.$getAppWebview();
                currentWebview.setStyle({  
                  pullToRefresh: {  
                    support: false,  
                    style: plus.os.name === 'Android' ? 'circle' : 'default'  
                  }  
                });  
                console.log('没有更多数据了,禁用');
            },
        },
        onPullDownRefresh() {  //下拉加载
            let _this = this;
            console.log('refresh');
            _this.listPage ++;
            _this.addList();
        }
    }
</script>


















































































<style>
    .content {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        padding: 30rpx;
        background-color: #FFFFFF;
    }







    .logo {
        height: 200rpx;
        width: 200rpx;
        margin: 30rpx 0;
    }



    .text-area {
        display: flex;
        justify-content: center;
    }
    .pull-content{
        position: relative;
        width: 100%;
        display: flex;
        align-items: center;
        margin: 30rpx 0;
    }
    .left-msg{
        width: 300rpx;
        border-radius: 10rpx;
        background-color: #9eea6b;
        color: #333;
        font-size: 30rpx;
        padding:20rpx;
    }
    .msg-right{
        justify-content: flex-end;
    }
    .img-box{
        display: flex;
        align-items: center;
        font-size: 28rpx;
    }
    .absolute-view{
        position: absolute;
        top: 0;
        left: 0;
        z-index: 10;
        width: 100%;
        height: 100%;
        background-color: #FFFFFF;
    }
    .show-index{
        display: none;
    }
    .msg-over{
        font-size: 24rpx;
        text-align: center;
        color: #999999;
    }
</style>
 












































易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!