小程式下拉重新整理
enablePullDownRefresh
enablePullDownRefresh是最容易實現下拉重新整理的方法,在json檔案中將enablePullDownRefresh設定為true,在Page中監聽onPullDownRefresh事件即可,支援點選頂部標題欄回到頂部,自定義標題欄時會失效,還可以通過直接呼叫wx.startPullDownRefresh()觸發下拉重新整理事件,產生下拉重新整理動畫,處理完下拉重新整理中的資料更新後呼叫wx.stopPullDownRefresh()結束動畫即可。
這種形式的下拉重新整理的優點很明顯就是簡單,沒有限制,但是缺點也同樣明顯:
- 下拉動畫太過簡單,互動不夠優雅且不能自定義下拉動畫
- 當自定義標題欄時,fixed定位,在Android下標題欄也會被一起下拉
scroll-view
scroll-view是官方的一個滾動檢視元件,使用很簡單,想要設定上拉重新整理程式碼如下:
<scroll-view class="scroll" scroll-y bindscrolltoupper="refresh">
<view class="content">content</view>
</scroll-view>
想要利用scroll-view實現上拉重新整理,需要注意:
- 一定要給scroll-view設定固定高度,否則監聽事件不會觸發
- 設定縱向滾動scroll-y
- scroll-view內的內容高度一定要比scroll-view高度要高,否則無法產生縱向滾動,就無法觸發監聽事件
scroll-view缺點:
- 由於iOS有橡皮筋效果,因此最終效果會與Android有一定的差異
- 剛開啟頁面時上拉是無法觸發上拉監聽事件,需要先向下滾動,觸發滾動,然後再上拉滾動才能觸發監聽事件
- 當有自定義頭部時,scroll-view需要一個高度計算,減去頭部高度
scroll-view優點:
- 可以自定義載入動畫
- 程式碼相對簡單
-
相對enablePullDownRefresh,scroll-view對滾動列表控制更加方便:
- scroll-into-view:滾動到指定元素
- enable-back-to-top:iOS點選頂部狀態列、安卓雙擊標題欄時,滾動條返回頂部,只支援豎向,且當自定義標題欄後就會失效
官方並不推薦使用scroll-view做下拉重新整理,官方文件上有這樣一個tip:
自定義下拉重新整理
自定義下拉重新整理最主要希望解決的問題還是在Android使用enablePullDownRefresh時fixed定位的標題欄或導航欄會被下拉的問題,同時兩端在下拉重新整理時的動畫保持一致,其實實現起來並不難,接下來就看看具體實現:
wxml:
<view class="scroll" bindtouchstart="touchStart" bindtouchmove="touchMove" bindtouchend="touchEnd">
<view class="animation">
<view class="loading"></view>
<text class="tip">{{state === 0 ? '下拉重新整理' : state === 1? '鬆開重新整理' : '重新整理中'}}</text>
</view>
<view style="transform: translateY({{translateHeight}}rpx)">
<slot name="content"></slot>
</view>
</view>
這個檔案定義元件的模版,有一個滾動view包裹,綁定了touch事件,裡面包含下拉重新整理時的動畫,和一個slot,slot用於插入滾動列表的內容
wxss:
.animation {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 150rpx;
margin-bottom: -150rpx;
background-color: #fff;
}
.loading {
width: 30rpx;
height: 30rpx;
border:6rpx solid #333333;
border-bottom: #cccccc 6rpx solid;
border-radius: 50%;
animation:load 1.1s infinite linear;
}
@keyframes load{
from{
transform: rotate(0deg);
}
to{
transform: rotate(360deg);
}
}
.tip {
margin-left: 10rpx;
color: #666;
}
樣式檔案這沒什麼特別的
js:
let lastY = 0 // 上一次滾動的位置
let scale = 750 / wx.getSystemInfoSync().windowWidth // rpx轉化比例
Component({
options: {
multipleSlots: true
},
data: {
scrollTop: 0,
translateHeight: 0, // 平移距離
state: -1
},
properties: {
// 觸發下拉重新整理的距離
upperDistance: {
type: Number,
value: 150
}
},
methods: {
// 監聽滾動,獲取scrollTop
onPageScroll (e) {
this.data.scrollTop = e.scrollTop
},
touchStart (e) {
lastY = e.touches[0].clientY
},
touchMove (e) {
let clientY = e.touches[0].clientY
let offset = clientY - lastY
if (this.data.scrollTop > 0 || offset < 0) return
this.data.translateHeight += offset
this.data.state = 0
lastY = e.touches[0].clientY
if (this.data.translateHeight - this.data.scrollTop * scale > this.data.upperDistance) {
this.data.state = 1
}
this.setData({
translateHeight: this.data.translateHeight,
state: this.data.state
})
},
touchEnd (e) {
if (this.data.translateHeight - this.data.scrollTop * scale > this.data.upperDistance) {
this.setData({
translateHeight: 150
})
this.triggerEvent('scrolltoupper')
this.setData({
state: 2
})
} else if (this.data.scrollTop <= 0) {
this.stopRefresh()
}
},
// 停止重新整理
stopRefresh () {
this.setData({
translateHeight: 0,
state: -1
}, () => {
wx.pageScrollTo({
scrollTop: 0,
duration: 0
})
})
}
}
})
這個下拉重新整理元件最重要的是控制下拉重新整理的時機,程式碼體現就是定義了一個upperDistance,下拉重新整理的距離來判斷是否執行重新整理。手指滑動時,獲取滑動距離,translateHeight累加用於展示,在touchEnd事件中判斷滑動距離是否達到設定值,達到設定值就傳送scrolltoupper事件,在父元件中監聽即可,否則停止重新整理。
資源搜尋網站大全 https://www.renrenfan.com.cn 廣州VI設計公司https://www.houdianzi.com
使用:
<header title="下拉重新整理" background="#fff"></header>
<refresh-scroll id="refreshScroll" bindscrolltoupper="refresh">
<view class="item" slot="content" wx:for="{{list}}">{{item}}</view>
</refresh-scroll>
Page({
data: {
list: []
},
onLoad: function () {
this.refreshScroll = this.selectComponent('#refreshScroll')
for (let i = 0; i < 10; i++) {
this.data.list.push(i)
}
this.setData({
list: this.data.list
})
},
onPageScroll (e) {
this.refreshScroll.onPageScroll(e)
},
onReachBottom () {
wx.showLoading({
title: 'onReachBottom'
})
setTimeout(() => {
wx.hideLoading()
}, 1000)
},
refresh: function (e) {
setTimeout(() => {
this.refreshScroll.stopRefresh()
}, 1000)
}
})
在使用時關鍵是要將頁面中onPageScroll中獲取的值傳遞下去,然後bindscrolltoupper監聽scrolltoupper事件,執行重新整理操作然後再呼叫stopRefresh停止重新整理,在真機測試時,表現都還不錯,當然了,這只是自定義下拉重新整理的一個簡單元件例子,如果需要用於到實際專案,可能還需要自己去完善,畢竟不同的人應用的場景不同,這裡只是給出了一個思路而已