虽然微信小程序自带了 onPullDownRefresh 事件可以监听用户的下拉动作,并可以在回调函数中进行下拉刷新列表的操作。但是有时候因为页面布局的关系,我们在页面上所展示的列表数据并不是直接在整个页面中进行布局的,而是放置在 scroll-view 这么一个组件中。
那么在这么个组件中,如何进行下拉刷新操作?
在 scroll-view 组件中自带了 bindscrolltoupper 事件,该事件在滚动条滚动到顶部/左边时触发。但是这么个事件远远不能满足我们的需要,因为我们还需要监听用户滑动的距离,并且在用户松开手指的瞬间进行页面刷新。
为此,我们可以考虑使用 js 原生的 touchstart、touchend、touchmove事件。
在 scroll-view 中定义这三个事件
bindtouchstart='touchStart'
bindtouchend='touchEnd'
bindtouchmove='touchMove'>
为了获取用户触摸的状态,我们需要在 data 中定义两个数据,
data: {
freshStatus: 'more', // 当前刷新的状态
showRefresh: false // 是否显示下拉刷新组件
}
基于这两个数据值,我们就可以写出下拉刷新的组件来,以下代码需要放置在 scroll-view 中
刷新中...
继续下拉刷新
释放刷新
首先是 showRefresh,它是个布尔型的数据,当用户下拉一定距离才显示这么个组件。然后就是 freshStatus 状态值,当用户下拉动作没有到一定距离(取值 ‘more’), 就显示 “继续下拉刷新” ;当用户下拉到满足刷新条件的距离时,freshStatus 取值 ‘end’,组件显示 “释放刷新”;而当用户松开手指后,就显示 “刷新中”,然后在事件处理中调用获取最新数据的函数,当数据刷新完后,设置 showRefresh 为 false,隐藏该组件。
以下是事件处理
// 触摸开始
touchStart(e) {
this.setData({
startY: e.changedTouches[0].pageY,
freshStatus: 'more'
})
},
// 触摸移动
touchMove(e) {
let endY = e.changedTouches[0].pageY;
let startY = this.data.startY;
let dis = endY - startY;
// 判断是否下拉
if (dis <= 0) {
return;
}
let offsetTop = e.currentTarget.offsetTop;
if (dis > 20) {
this.setData({
showRefresh: true
}, () => {
if (dis > 50) {
this.setData({
freshStatus: 'end'
})
} else {
this.setData({
freshStatus: 'more'
})
}
})
} else {
this.setData({
showRefresh: false
})
}
},
// 触摸结束
touchEnd(e) {
if (this.data.freshStatus == 'end') {
// 延迟 500 毫秒,显示 “刷新中”,防止请求速度过快不显示
setTimeout(()=>{
this.getList(); // 获取最新列表数据
}, 500);
} else {
this.setData({
showRefresh: false
})
}
},
还有相关 wxss
.lzy-loading{
margin-right: 20rpx;
float: left;
width: 40rpx;
height: 40rpx;
border-radius: 50%;
border: 1px solid #f0f0f0;
border-left: 1px solid #6190E8;
animation: load 1s linear infinite;
-webkit-animation: load 1s linear infinite;
}
@-webkit-keyframes load
{
from{-webkit-transform:rotate(0deg);}
to{-webkit-transform:rotate(360deg);}
}
@keyframes load
{
from{transform:rotate(0deg);}
to{transform:rotate(360deg);}