uni-app scroll-view组件的scroll-top属性在使用滚动到底部之后,手动滚动页面之后再次操作不会再滚回底部

uni-app scroll-view组件的scroll-top属性在使用滚动到底部之后,手动滚动页面之后再次操作不会再滚回底部

开发环境 版本号 项目创建方式
Windows win7 HBuilderX

产品分类:uniapp/小程序/微信

示例代码:

<scroll-view   
    scroll-y="true"   
    class="chat-scroll"  
    :scroll-top="scrollTop"  
    :scroll-with-animation="true"  
    @scroll="fnScroll"  
>
    <view class="chat-msg-list">  
        <view class="chat-msg-ctn">  
            <view class="msg-ctn flex-r-e" v-for="item in msgList">  
                <view class="msg-content-ctn msg-self">  
                    <view class="msg-content self-content">123</view>  
                </view>  
            </view>  
        </view>  
    </view>  
</scroll-view>  
<view class="consult-finish-ctn" @click="fnFinish">结束</view>  
export default {  
    onLoad(){  

    },  
    data(){  
        return{  
            scrollTop:0,  
            msgList:5  
        }  
    },  
    methods:{  
        fnGetMsgHeight(){  
            let query = uni.createSelectorQuery();  
            query.select('.chat-msg-list').boundingClientRect(res => {  
              let height = res.height  
              this.scrollTop = height  
            }).exec();  
        },  
        fnFinish(){  
            this.msgList = 20  
            this.fnGetMsgHeight()  
        }  
    }  
}  
.chat-scroll{  
    width:100%;  
    height: calc(100vh - 402rpx);  
    margin-top: 290rpx;  
    .chat-msg-list{  
        width:100%;  
        .chat-msg-ctn{  
            width:100%;  
            padding:0 40rpx;  
            .msg-ctn{  
                width:100%;  
                margin-bottom: 30rpx;  
                .msg-content-ctn{  
                    max-width:466rpx;  
                    padding:23rpx;  
                    border-radius: 12rpx;  
                    position: relative;  
                    .msg-content{  
                        font-size: 30rpx;  
                        line-height: 36rpx  
                    }  
                    .self-content{  
                        color:#fff  
                    }  
                    .friend-content{  
                        color:#333  
                    }  

                }  
                .msg-self{  
                    background: #4166F7;  
                    margin-right: 30rpx;  
                }  
                .msg-friend{  
                    background: #fff;  
                    margin-left: 30rpx;  
                }  

            }  
        }  
    }  
}  
.consult-finish-ctn{  
    width: 108rpx;  
    height: 108rpx;  
    background: #7590F9;  
    border-radius: 50%;  
    position: fixed;  
    right:30rpx;  
    bottom:187rpx;  
    text-align: center;  
    line-height: 108rpx;  
    color: #fff;  
    font-size: 30rpx;  
}

操作步骤:

  • 先点击结束按钮,会滚动到页面底部,手动将页面滚回顶部,再次点击结束按钮,页面无法再滚动到最底部

预期结果:

  • 预期结果,手动滚回顶部后,再次点击结束按钮扔能滚动到最底部(小程序官方语言是可以实现)

实际结果:

  • 手动滚回顶部后,再次点击结束按钮无法实现滚动

bug描述:

  • scroll-view组件的scroll-top属性在使用滚动到底部之后,元素高度没有改变,手动将页面滚回顶部,再次用事件触发滚动到底部不生效

更多关于uni-app scroll-view组件的scroll-top属性在使用滚动到底部之后,手动滚动页面之后再次操作不会再滚回底部的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

vue 的观测限制,看下 scroll-view 文档也有说明和解决方案。

更多关于uni-app scroll-view组件的scroll-top属性在使用滚动到底部之后,手动滚动页面之后再次操作不会再滚回底部的实战教程也可以访问 https://www.itying.com/category-93-b0.html


这是一个典型的 scroll-view 组件在动态设置 scroll-top 时遇到的常见问题。问题核心在于 scroll-top 属性在值未变化时不会触发重新滚动。

在你的代码中,当第一次点击结束按钮时,scrollTop 从 0 变为 height,页面滚动到底部。之后手动滚动回顶部,scrollTop 的值在逻辑上仍然是 height。此时再次点击按钮,fnGetMsgHeight() 计算出的新高度很可能与当前的 scrollTop 值相同(或非常接近),由于 scroll-top 属性被设置为相同的值,组件不会执行滚动动画。

解决方案:

你需要强制 scrollTop 的值发生变化来触发滚动。一个可靠的做法是在设置目标值前,先将其重置为 0(或一个很小的值),然后在下一个事件循环中(使用 $nextTicksetTimeout)再设置为目标高度。这确保了 scroll-top 属性值经历了 A -> B -> A 的变化过程,从而驱动滚动行为。

修改你的 fnGetMsgHeight 方法如下:

fnGetMsgHeight() {
    // 1. 先将 scrollTop 重置为0,强制触发一次变化
    this.scrollTop = 0;
    
    // 2. 在下一个事件循环中,获取真实高度并设置
    this.$nextTick(() => {
        let query = uni.createSelectorQuery();
        query.select('.chat-msg-list').boundingClientRect(res => {
            if (res) {
                let height = res.height;
                // 这里可以额外加一个很小的值,确保数值绝对变化
                this.scrollTop = height + 0.1; 
                // 如果担心浮点数问题,也可以使用 height ? height + 1 : 0
            }
        }).exec();
    });
}
回到顶部