当前位置:   article > 正文

微信小程序scroll-view下拉刷新(附带下拉刷新效果)_scroll-view 下拉

scroll-view 下拉

微信小程序scroll-view下拉刷新(附带下拉刷新效果)

背景
  1. 在微信小程序上如果使用了scroll-view ,是没办法通过页面上的onPulldownRefresh函数触发下拉刷新的(重点解决的问题)
  2. 如果小程序页面上有顶部栏导航栏之类的,在下拉刷新的时候会把顶部栏一起拖下
  3. 想自定义下拉刷新的效果
解决方法
  • 核心思路:通过监听touchstart和touchend 事件来记录e.changedTouches[0].pageY,然后通过比较就能知道是不是下拉手势
  • 基于以上思路,为了开发者方便使用,自己实现了一个下拉刷新组件
    https://download.csdn.net/download/u012308481/11985615
  • 下拉刷新效果如下图
    在这里插入图片描述
组件调用方法

wxml

//json文件记得引入组件
<super-scroll-view  bind:lower="mylower" height="{{height}}px" bind:pulldown="myOnPullDownRefresh">
	<view>你的内容</view>
	<view>你的内容</view>
	<view>你的内容</view>
	<view>你的内容</view>
	<view>你的内容</view>
</super-scroll-view>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

js

Page({
  myOnPullDownRefresh: function (event) {
  	//模拟数据请求 
    setTimeout(() => {
    	event.detail.resolve();//告诉组件完成下拉刷新,如果超过5s不调用,下拉刷新效果也会消失
	}, 1000)
  },
  mylow:function(){
  	//todo 这里会触发触底事件,可以处理自己的上拉加载逻辑
  }
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
tips
  1. 可以设置不使用组件下拉刷新效果
<super-scroll-view  ball="{{false}}" bind:lower="mylower" height="{{height}}px" bind:pulldown="myOnPullDownRefresh">
	<view>你的内容</view>
	<view>你的内容</view>
	<view>你的内容</view>
	<view>你的内容</view>
	<view>你的内容</view>
</super-scroll-view>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
源码
  • js
const timeout = 5000;
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    height:{
      type:String,
      value:'100%'
    },
    ball:{
      type:Boolean,
      value:true
    }
  },
  /**
   * 组件的初始数据
   */
  data: {
    isBusy:false,
    status: 0,  //0:正常状态 1:加载中状态
    freshBall:{
      maxBallTop: 80,//刷新球最大下拉距离
      top:0,//刷新球位置
      show:true,
      isLoading:false,
      deg:0,//旋转角度
      step:1.8//步长 
    },
    isTop: true,//是否在顶部
    touchStartY: 0,//刚触碰屏幕时 距离顶部的距离
    touchMoveHeight: 0 //触碰屏幕时 手指移动的距离
  },
  attached(options) {
    console.log(options)
  },
  /**
   * 组件的方法列表
   */
  methods: {
    touchstart(){
      const query = wx.createSelectorQuery()
      query.select('#s-scroll-view').scrollOffset()
      query.exec(function (res) {
        console.log(res)
      })
    },
    bindscroll: function (e) {
      //console.log(e)
      let self = this;
      self.setData({
        isTop: false
      })
    },
    touchStart: function (e) {
      //console.log(e)
      let self = this;
      self.setData({
        touchStartY: e.changedTouches[0] && e.changedTouches[0].pageY,
        isTop: true
      })
    },
    touchMove: function (e) {
      //console.log(e)
      let self = this;
      let touchStartY = self.data.touchStartY;
      let touchMoveY = e.changedTouches[0] && e.changedTouches[0].pageY;
      self.setData({
        touchMoveHeight: touchMoveY - touchStartY
      })
      if (!this.data.isBusy && this.data.isTop){
        this.data.freshBall.top = this.data.touchMoveHeight > this.data.freshBall.maxBallTop * this.data.freshBall.step ? this.data.freshBall.maxBallTop : this.data.touchMoveHeight/this.data.freshBall.step;
        this.data.freshBall.deg = this.getDegByHeight(this.data.freshBall.top);
        this.data.freshBall.isLoading=false;
        this.setData({freshBall:this.data.freshBall});
      }
    },
    touchEnd: function (e) {
      //console.log(e)
      let self = this;
      let isTop = self.data.isTop;
      let touchStartY = self.data.touchStartY;
      let touchEndY = e.changedTouches[0] && e.changedTouches[0].pageY;
      //console.log(isTop)
      //console.log(touchStartY)
      //console.log(touchEndY)
      if (!this.data.isBusy && isTop && touchEndY-this.data.freshBall.maxBallTop*this.data.freshBall.step > touchStartY ) {
        console.log("触发下拉刷新");
        this.data.freshBall.isLoading = true;
        this.setData({ freshBall: this.data.freshBall });
        let timeId = null;
        new Promise((resolve,reject)=>{
          this.triggerEvent('pulldown', {resolve});
          timeId = setTimeout(()=>{
            resolve();
          },timeout)
        }).then((data)=>{
          if(!timeId)return;
          clearTimeout(timeId);
          timeId = null;
          this.data.freshBall.top = 0;
          this.setData({ freshBall: this.data.freshBall });
          this.setData({ isBusy: false });
        }).catch(e=>{
          if (!timeId) return;
          clearTimeout(timeId);
          this.data.freshBall.top = 0;
          this.setData({ freshBall: this.data.freshBall });
          this.setData({ isBusy: false });
        })
        this.setData({isBusy:true,touchMoveHeight:0});
      }else{
        this.data.freshBall.top = 0;
        this.setData({ freshBall: this.data.freshBall });
      }
    },
    lower(e) {
      //console.log(e)
      if (!this.data.isBusy) {
        console.log("触底")
        this.triggerEvent('lower')
        this.setData({ isBusy: true })
        setTimeout(() => {
          this.setData({ isBusy: false });
        }, 500)
      }
    },
    getDegByHeight(height){
      let maxBallTop = this.data.freshBall.maxBallTop;
      return height/maxBallTop*360; 
    },
    resetFreshBall(){//重置刷新球
      this.setData({
        maxBallTop: 100,
        top:0,
        show:true,
        deg:0,
        isLoading:false,
        step:2
      });
    }
  }
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • html
<view wx:if="{{ball}}" class="freshball" style="transform:translateY({{freshBall.top}}px);opacity:{{freshBall.top<=0?0:1}}">
  <image class="freshImg" src="resources/freshball.svg" style="transform:rotate({{freshBall.deg}}deg);display:{{freshBall.isLoading?'none':'block'}}"></image>
  <image style="display:{{!freshBall.isLoading?'none':'block'}}" class="loading" src="resources/loading.svg"></image>
</view>
<view class="superScrollView">
  <scroll-view style="height:{{height}}" scroll-y bindscrolltolower="lower" bindscroll="bindscroll" bindtouchstart="touchStart" bindtouchend="touchEnd" catchtouchmove="touchMove">
    <view class="scrollWrap">
      <slot />
    </view>
  </scroll-view>
</view>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • css
 .superScrollView{
 height:100%;
}
.scrollView{
 height:100%;
}
.scrollWrap{
 min-height:100%;
}
.freshball{
 background:white;
 border-radius: 50%;
 width:80rpx;
 height:80rpx;
 display:flex;
 justify-content: center;
 align-items: center;
 position:fixed;
 top:0;
 left:50%;
 margin-left:-40rpx;
 margin-top:-80rpx;
 box-sizing: border-box;
 z-index:999;
 box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
 transition:all 0.3s;
 overflow:hidden;
}
.freshball .freshImg{
 width:67%;
 height:67%;
 display:block;
 transform-origin: center center;
 transition:all 0.1s;
}
.freshball .loading{
 width:70%;
 height:70%;
 display:block;
 transform-origin: center center;
 animation:loading 1s infinite;
}
@keyframes loading
{
 from {transform:rotate(0deg)}
 to {transform: rotate(360deg)}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号