移動端下拉刷新和上拉加載實現

最近在作移動端開發,移動端的性能不如 PC 端,屏幕頁沒有 PC 大,須要咱們優化的東西不少;在工做中我所作的移動端小頁面,無一例外的都是將網頁嵌入到安卓或者 IOS 裏面去。css

上拉加載

問題:若是數據太多前端一次性渲染或者請求全部數據,就不能作到用戶體驗和用戶效果最佳 解決方案: 移動端分頁,滾動到頁面底部從新請求接口,而後把上次請求的數據和這一次請求的數據拼接到一個數組裏面html

關於原生的滾動 scroll 事件會失效這個問題坑大了,有興趣能夠看看 解決工做bug或者需求系列文章前端

由於用的是 vue 因此會好一點,沒有那麼坑,可是不少 css 樣式都是缺一不可的 實現代碼:vue

<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 事件,這個還好,沒啥問題git

實現代碼:github

<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下拉刷新和上拉加載實現原理淺析segmentfault

大概原理是這樣的,樣式什麼的瞎寫的,有興趣能夠本身好好寫一下樣式。數組

H5下拉刷新和上拉加載實現bash

博客會保持隨時更新 sunseekers.cn/app

相關文章
相關標籤/搜索