【微信小程序】scroll-view 的上拉加載和下拉刷新

  一、在微信小程序中,想到 下拉刷新 和 上拉加載,若是是整個頁面都拖動的話,能夠在頁面配置中,配置 enablePullDownRefresh 和 onReachBottomDistance 而後在 .js 中 使用 Page.onPullDownRefreshPage.onReachButton 這樣來進行。html

  二、上面的作法是官方推薦咱們作頁面的 下拉刷新 和 上拉加載 所使用的方法。但某種狀況好比頭部是固定的,但使用上面的方法,整個頁面都拉動,會顯得很奇怪。這個時候,咱們的滾動其實是使用了 scroll-view 來進行的,會顯得更加好看。小程序

  三、使用 scroll-view 的話,會想到的是 bindscrolltoupper 和 bindscrolltolower,但其實使用這個兩個也仍是會出現問題的。這個問題是 bindscrolltoupper 會觸發屢次,並且一開始在頂部的時候,有可能沒有響應到。微信小程序

  

  下面的方法是使用 touchstart 和 touchend 來實現的 上拉加載 和 下拉刷新:微信

1 <scroll-view id="scroll-wrap"
2              scroll-y
3              bindtouchstart="start_fn" 
4              bindtouchend="end_fn">
5     // 列表
6 </scroll-view>   

 

  一般咱們都寫法,都如上面同樣,但由於要拿到滾動的最大高度,因此須要寫成下面的樣式:app

1 <scroll-view id="scroll-wrap"
2              scroll-top="{{scroll_top}}"
3              scroll-y>
4      <view id="inner-wrap"
5            bindtouchstart="start_fn" 
6            bindtouchend="end_fn">
7        // 列表
8      </view>
9 </scroll-view>

 

  咱們須要獲取 scroll-wrap 和 inner-wrap 的高度。學習

 1 Page({
 2     data: {
 3        height: 0, // scroll-wrap 的高度,這個高度是固定的
 4        inner_height: 0, // inner-wrap 的高度,這個高度是動態的
 5        scroll_top: 0, // 滾動到位置。
 6        start_scroll: 0, // 滾動前的位置。
 7        touch_down: 0 // 觸摸時候的 Y 的位置
 8     },
 9     // start: onLoad 生命週期
10     onLoad () {
11        let self = this;
12        wx.createSelectorQuery().select('scroll-wrap').boundingClientReact(function (rect) {
13            self.data.height = rect.height;
14        }).exec();
15     }
16     // end: onLoad 生命週期
17 });

 

  由於scroll-view 要在垂直方向上能夠滾動,須要設置height 的高度,因此一般狀況下,只要獲取一次就好了,若是scroll-view 由於某個元素消失掉,影響了高度的話,記得要更新 height 的值。優化

  接下來就是 bindtouchstart 和 bindtouchend 的配合:動畫

bindtouchstart  ----  start_fn:this

 1 // start: 觸摸開始
 2 start_fn (e) {
 3     let self = this;
 4     let touch_down = e.touches[0].clientY;
 5     this.data.touch_down = touch_down;
 6     // 獲取 inner-wrap 的高度
 7     wx.createSelectorQuery().select('#inner-wrap').boundingClientRect(function (rect) {
 8         self.data.inner_height = rect.height;
 9     }).exec();
10    
11     // 獲取 scroll-wrap 的高度和當前的 scrollTop 位置
12     wx.createSelectorQuery().select('#scroll-wrap').fields({
13         scrollOffset: true,
14         size: true
15     }, function (rect) {
16         self.data.start_scroll = rect.scrollTop;
17         self.data.height = rect.height;
18     }).exec();
19 } 
20 // end: 觸摸開始

 

bindtouchend  ----  end_fn:spa

 1 // start: 觸摸結束
 2 end_fn (e) {
 3     let current_y = e.changedTouches[0].clientY;
 4     let self = this;
 5     let { start_scroll, inner_height, height, touch_down } = this.data;
 6     /**
 7     * 一、下拉刷新
 8     * 二、上拉加載
 9     */
10     if (current_y > touch_down && current_y - touch_down > 20 && start_scroll == 0) {
11         // 下拉刷新 的請求和邏輯處理等
12     } else if (current_y < touch_down && touch_down - current_y >= 20 && inner_height - height == start_scroll) {
13        // 上拉加載 的請求和邏輯處理等
14     }
15 }
16 // end: 觸摸結束

  原理就是觸摸的時候,檢查是否在頂部或者是底部,若是在頂部,還進行下拉,就進行刷新;若是在底部了,還進行上拉,就進行加載。使用 touchstart 和 touchend 的問題是用戶必需要手指離開纔會觸發到。若是想要在頂部下拉就刷新,能夠在 touchmove 中進行判斷。

  須要注意的是,使用上面的方法,會使 scroll-view 上 綁定 bindscroll 、bindscrolltopupper 和 bindscrolltoploweper 等方法是無效的。

  樣式和動畫效果的優化,本身去進行吧。

  若是有更好的方法,能夠在評論下,留下你的方法供你們學習。 

  這一篇的方法只適合安卓機的,但仍是保留下來。

相關文章
相關標籤/搜索