小程序scroll-view自定義下拉刷新

雖然微信小程序自帶了 onPullDownRefresh 事件能夠監聽用戶的下拉動做,並能夠在回調函數中進行下拉刷新列表的操做。可是有時候由於頁面佈局的關係,咱們在頁面上所展現的列表數據並非直接在整個頁面中進行佈局的,而是放置在 scroll-view 這麼一個組件中。javascript

那麼在這麼個組件中,如何進行下拉刷新操做?css

在 scroll-view 組件中自帶了 bindscrolltoupper 事件,該事件在滾動條滾動到頂部/左邊時觸發。可是這麼個事件遠遠不能知足咱們的須要,由於咱們還須要監聽用戶滑動的距離,而且在用戶鬆開手指的瞬間進行頁面刷新。html

爲此,咱們能夠考慮使用 js 原生的 touchstart、touchend、touchmove事件。java

在 scroll-view 中定義這三個事件web

<scroll-view scroll-y style="height:100%" 
  bindtouchstart='touchStart'
  bindtouchend='touchEnd'
  bindtouchmove='touchMove'>
</scroll-view>

爲了獲取用戶觸摸的狀態,咱們須要在 data 中定義兩個數據,小程序

data: {
    freshStatus: 'more', // 當前刷新的狀態
    showRefresh: false   // 是否顯示下拉刷新組件
  }

基於這兩個數據值,咱們就能夠寫出下拉刷新的組件來,如下代碼須要放置在 scroll-view 中微信小程序

<view wx:if="{{showRefresh}}" style='width:100%;position:relative;padding:60rpx 0;'>
    <view class="text-gray" style='position: absolute;left: 50%;top: 50%;transform: translate(-50%, -50%);'>
      <view wx:if="{{freshStatus == 'fresh'}}" class="flex">
        <view class="lzy-loading"></view>
        <view>刷新中...</view>
      </view>
      <view class="text" wx:elif="{{freshStatus == 'more'}}">
        <!-- 使用到了 colorUI 下拉箭頭圖標 -->
        <text class="cuIcon-refresharrow"></text> 繼續下拉刷新
      </view>
      <view class="text" wx:else>
        釋放刷新
      </view>
    </view>
  </view>

首先是 showRefresh,它是個布爾型的數據,當用戶下拉必定距離才顯示這麼個組件。而後就是 freshStatus 狀態值,當用戶下拉動做沒有到必定距離(取值 ‘more’), 就顯示 「繼續下拉刷新」 ;當用戶下拉到知足刷新條件的距離時,freshStatus 取值 ‘end’,組件顯示 「釋放刷新」;而當用戶鬆開手指後,就顯示 「刷新中」,而後在事件處理中調用獲取最新數據的函數,當數據刷新完後,設置 showRefresh 爲 false,隱藏該組件。api

如下是事件處理微信

// 觸摸開始
    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
        })
      }
    },

還有相關 wxssxss

.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);}
相關文章
相關標籤/搜索