主题
页面滚动
页面级滚动由页面和 Page 生命周期控制;局部滚动由 scroll-view 控制。一个页面应明确由谁承载主滚动,避免在页面滚动与纵向 scroll-view 之间嵌套竞争手势。
页面级滚动
滚动到指定位置
wx.pageScrollTo 用于控制整个页面的滚动位置,适合返回顶部、跳到章节和恢复阅读位置。
js
wx.pageScrollTo({
scrollTop: 0,
duration: 300,
})需要滚到指定元素时,先通过 SelectorQuery 获取元素相对页面的位置,再调用 wx.pageScrollTo。
js
const query = wx.createSelectorQuery()
query.select('#section-order').boundingClientRect()
query.selectViewport().scrollOffset()
query.exec(([rect, viewport]) => {
if (!rect) return
wx.pageScrollTo({
scrollTop: viewport.scrollTop + rect.top,
duration: 300,
})
})监听页面滚动
在页面的 onPageScroll 中获取滚动位置。常用于吸顶导航、滚动后显示返回顶部按钮,以及根据滚动距离调整导航栏样式。
js
Page({
onPageScroll({ scrollTop }) {
this.setData({ showBackToTop: scrollTop > 400 })
},
})滚动事件触发频繁,不要在回调中执行复杂计算或频繁请求;仅在状态变化时调用 setData。
触底加载与下拉刷新
onReachBottom:页面触底时加载下一页数据;触发距离由页面配置onReachBottomDistance控制。onPullDownRefresh:用户在页面顶部下拉时刷新数据;需在页面配置中启用enablePullDownRefresh,完成后调用wx.stopPullDownRefresh()。
js
Page({
async onPullDownRefresh() {
try {
await this.loadFirstPage()
} finally {
wx.stopPullDownRefresh()
}
},
onReachBottom() {
this.loadNextPage()
},
})分页请求应避免并发触发,并在没有更多数据时停止加载。
局部滚动:scroll-view
scroll-view 适合聊天记录、横向标签栏和固定头尾之间的列表区域。通过 scroll-top、scroll-left 或 scroll-into-view 控制位置;通过 bindscroll、bindscrolltolower 等事件响应滚动和触底。
局部列表的加载更多应监听 bindscrolltolower,而不是页面的 onReachBottom。
xml
<scroll-view
class="list"
scroll-y
scroll-into-view="{{activeId}}"
bindscrolltolower="loadMore"
>
<view wx:for="{{items}}" wx:key="id" id="item-{{item.id}}">
{{item.name}}
</view>
</scroll-view>高度自适应
纵向 scroll-view 必须具有可确定的高度。固定区域与滚动区域共存时,可将页面设为纵向 flex 容器,并以 flex: 1 填充剩余空间。
xml
<view class="page">
<swiper class="banner" indicator-dots>
<swiper-item wx:for="{{banners}}" wx:key="id">
<image src="{{item.image}}" mode="aspectFill" />
</swiper-item>
</swiper>
<view class="scroll-wrapper">
<scroll-view class="list" scroll-y bindscrolltolower="loadMore">
<view wx:for="{{items}}" wx:key="id" class="card">{{item.name}}</view>
</scroll-view>
</view>
</view>css
page {
height: 100%;
}
.page {
height: 100%;
display: flex;
flex-direction: column;
}
.banner {
height: 400rpx;
}
.scroll-wrapper {
flex: 1;
min-height: 0;
}
.list {
height: 100%;
}min-height: 0 允许 flex 子项收缩,避免内容撑开容器而无法滚动。
