前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >移动端下拉刷新和上拉加载实现

移动端下拉刷新和上拉加载实现

作者头像
sunseekers
发布2019-08-09 15:38:53
1.6K0
发布2019-08-09 15:38:53
举报
文章被收录于专栏:我和我大前端的故事

最近在做移动端开发,移动端的性能不如 PC 端,屏幕页没有 PC 大,需要我们优化的东西很多;在工作中我所做的移动端小页面,无一例外的都是将网页嵌入到安卓或者 IOS 里面去。

上拉加载

问题:如果数据太多前端一次性渲染或者请求所有数据,就不能做到用户体验和用户效果最佳 解决方案: 移动端分页,滚动到页面底部重新请求接口,然后把上次请求的数据和这一次请求的数据拼接到一个数组里面

关于原生的滚动 scroll 事件会失效这个问题坑大了,有兴趣可以看看 解决工作bug或者需求系列文章

因为用的是 vue 所以会好一点,没有那么坑,但是很多 css 样式都是缺一不可的 实现代码:

代码语言:javascript
复制
<template>
  <div class='wrapper'>
    <p class="refreshText">{{text}}</p>
    <ul class='refreshContainer' @touchstart='getStart' @touchmove='getMove' @touchend='getEnd' @scroll="onScroll($event)">
      <li class='freshContainer' v-for='item in listData' :key='item.value'>{{item.label}}</li>
    </ul>
  </div>
</template>
<script>
export default {
//   当前手势滑动位置与初始位置差值大于零时,提示正在进行下拉刷新操作;
// 下拉到一定值时,显示松手释放后的操作提示;
// 下拉到达设定最大值松手时,执行回调,提示正在进行更新操作。
  data(){
    return {
      text:"",
      listData:[{
        label:'测试数据001',
        value:'hjh'
      },{
        label:'测试数据002',
        value:2
      },{
        label:'测试数据003',
        value:3
      },{
        label:'测试数据004',
        value:4
      },{
        label:'测试数据005',
        value:5
      },{
        label:'测试数据006',
        value:6
      },{
        label:'测试数据007',
        value:7
      },{
        label:'测试数据008',
        value:8
      },{
        label:'测试数据009',
        value:9
      },{
        label:'测试数据010',
        value:10
      },{
        label:'测试数据0011',
        value:11
      }]
    }
  },
  methods:{
    onScroll (event) { 
         const target = event.target
        // 滚动条的总高度
        const scrollHeight = target.scrollHeight
        // 可视区的高度
        const clientHeight = target.clientHeight
        // 距离顶部的距离
        const scrollTop = target.scrollTop
        console.log('滚动条的总高度',scrollHeight);
        console.log('可视区的高度',clientHeight);
        console.log('距离顶部的距离',scrollTop);

        // 滚动到底部
        if (scrollTop + clientHeight >= scrollHeight - 80) {
          // 这里可以进行数据分页请求了this.getListMore
          this.listData.push({
        label:'测试数据0012',
        value:12
      },{
        label:'测试数据0013',
        value:13
      },{
        label:'测试数据004',
        value:14
      },{
        label:'测试数据0015',
        value:15
      },{
        label:'测试数据0016',
        value:1
      },{
        label:'测试数据0016',
        value:16
      },{
        label:'测试数据0017',
        value:17
      },{
        label:'测试数据0018',
        value:18
      },{
        label:'测试数据0019',
        value:19
      },{
        label:'测试数据00100',
        value:100
      },{
        label:'测试数据00101',
        value:101
      },{
        label:'测试数据00102',
        value:102
      },{
        label:'测试数据00103',
        value:103
      })
          console.log('滚动事件',event);
        } 
    }
  }
}
</script>

<style>
html,
body,
.body-container {
  height: 100%;//必须有
}
.wrapper {
  width: 100%;
  height: 100%;//必须有
}
ul {
  height: 100%;//必须有
  border: 1px red solid;
  overflow: auto;//必须有
}
ul li {
  width: 100%;
  line-height: 100px;
  /* border: 1px red solid; */
  text-align: center;
}
.refreshText {
  display: flex;
  justify-content: center;
  align-items: center;
  /* height: 50px; */
  border: 1px red solid;
}
</style>
复制代码

问题: 下拉实现数据更新

解决方案: 监听原生的 touchstart,touchmove,touchend 事件,这个还好,没啥问题

实现代码:

代码语言:javascript
复制
    <p class="refreshText">{{text}}</p>
    <ul class='refreshContainer' @touchstart='getStart' @touchmove='getMove' @touchend='getEnd'>
      <li v-for='item in listData' :key='item.value'>{{item.label}}</li>
    </ul>
    <script>
export default {
//   当前手势滑动位置与初始位置差值大于零时,提示正在进行下拉刷新操作;
// 下拉到一定值时,显示松手释放后的操作提示;
// 下拉到达设定最大值松手时,执行回调,提示正在进行更新操作。
  data(){
    return {
      text:"",
      listData:[{
        label:'测试数据001',
        value:'hjh'
      },{
        label:'测试数据002',
        value:2
      },{
        label:'测试数据003',
        value:3
      },{
        label:'测试数据004',
        value:4
      },{
        label:'测试数据005',
        value:5
      },{
        label:'测试数据006',
        value:6
      },{
        label:'测试数据007',
        value:7
      },{
        label:'测试数据008',
        value:8
      },{
        label:'测试数据009',
        value:9
      },{
        label:'测试数据010',
        value:10
      },{
        label:'测试数据0011',
        value:11
      },{
        label:'测试数据0012',
        value:12
      },{
        label:'测试数据0013',
        value:13
      },{
        label:'测试数据004',
        value:14
      },{
        label:'测试数据0015',
        value:15
      },{
        label:'测试数据0016',
        value:1
      },{
        label:'测试数据0016',
        value:16
      },{
        label:'测试数据0017',
        value:17
      },{
        label:'测试数据0018',
        value:18
      },{
        label:'测试数据0019',
        value:19
      },{
        label:'测试数据00100',
        value:100
      },{
        label:'测试数据00101',
        value:101
      },{
        label:'测试数据00102',
        value:102
      },{
        label:'测试数据00103',
        value:103
      }],
      startPosition:0,
      movePostion:0,
      refreshContainer:"",
      refreshText:""
    }
  },
  methods:{
    getStart(e){
      this.refreshContainer = document.querySelector('.refreshContainer')
      this.startPosition = e.touches[0].pageY
      this.refreshContainer.style.position = 'relative';
      this.refreshContainer.style.transition = 'transform 0s';
    },
    getMove(e){
      this.movePostion = e.touches[0].pageY
      let transitionHeight = this.movePostion - this.startPosition
      this.refreshText = document.querySelector('.refreshText')
      if(transitionHeight > 0 &&transitionHeight < 50){
      this.refreshText.style.height = transitionHeight+'px';
      }else{
      this.refreshText .style.height = '50px';
      }
      if (transitionHeight > 0 && transitionHeight < 100) {
            this.text = '下拉刷新';
            this.refreshContainer.style.transform = 'translateY('+transitionHeight+'px)';
            if (transitionHeight > 50) {
              this.text = '释放更新';
            }
        } 
    },
    getEnd(){
      this.refreshContainer.style.transition = 'transform 0.5s ease 1s';
        this.refreshContainer.style.transform = 'translateY(0px)';
        this.text = '更新中...';
        this.refreshText.style.height = '0px';
        this.text = '';
        // 接口请求什么的事情

    },
  }
}
</script>

复制代码

详细介绍请参考H5下拉刷新和上拉加载实现原理浅析

大概原理是这样的,样式什么的瞎写的,有兴趣可以自己好好写一下样式。

H5下拉刷新和上拉加载实现

博客会保持随时更新 sunseekers.cn/

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019年08月09日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 上拉加载
  • 问题: 下拉实现数据更新
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档