zoukankan      html  css  js  c++  java
  • H5下拉刷新和上拉加载实现原理浅析

    前言

    在移动端H5网页中,下拉刷新和上拉加载更多数据的交互方式出现频率很高,开源社区也有很多类似的解决方案,如iscroll,pulltorefresh.js库等。下面是对这两种常见交互基本实现原理的阐述。

    实现原理

    下拉刷新

    实现下拉刷新主要分为三步:

    • 监听原生touchstart事件,记录其初始位置的值,e.touches[0].pageY
    • 监听原生touchmove事件,记录并计算当前滑动的位置值与初始位置值的差值,大于0表示向下拉动,并借助CSS3的translateY属性使元素跟随手势向下滑动对应的差值,同时也应设置一个允许滑动的最大值;
    • 监听原生touchend事件,若此时元素滑动达到最大值,则触发callback,同时将translateY重设为0,元素回到初始位置。

    示例。查看链接:下拉刷新demo(PC浏览器需调成手机模拟器模式查看)

    <main>
        <p class="refreshText"></p>
        <ul id="refreshContainer">
            <li>111</li>
            <li>222</li>
            <li>333</li>
            <li>444</li>
            <li>555</li>
            ...
        </ul>
    </main>
    (function(window) {
        var _element = document.getElementById('refreshContainer'),
          _refreshText = document.querySelector('.refreshText'),
          _startPos = 0,
          _transitionHeight = 0;
    
        _element.addEventListener('touchstart', function(e) {
            console.log('初始位置:', e.touches[0].pageY);
            _startPos = e.touches[0].pageY;
            _element.style.position = 'relative';
            _element.style.transition = 'transform 0s';
        }, false);
    
        _element.addEventListener('touchmove', function(e) {
            console.log('当前位置:', e.touches[0].pageY);
            _transitionHeight = e.touches[0].pageY - _startPos;
    
            if (_transitionHeight > 0 && _transitionHeight < 60) {
                _refreshText.innerText = '下拉刷新';
                _element.style.transform = 'translateY('+_transitionHeight+'px)';
    
                if (_transitionHeight > 55) {
                  _refreshText.innerText = '释放更新';
                }
            }                
        }, false);
    
        _element.addEventListener('touchend', function(e) {
            _element.style.transition = 'transform 0.5s ease 1s';
            _element.style.transform = 'translateY(0px)';
            _refreshText.innerText = '更新中...';
    
            // todo...
    
        }, false);
    })(window);

    在下拉到松手的过程中,经历了三个状态:

    • 当前手势滑动位置与初始位置差值大于零时,提示正在进行下拉刷新操作;
    • 下拉到一定值时,显示松手释放后的操作提示;
    • 下拉到达设定最大值松手时,执行回调,提示正在进行更新操作。

    上拉加载

    上拉加载更多数据是在页面滚动时触发的动作,一般是页面滚动到底部时触发,也可以选择在滚动到一定位置的时候触发。

    以滚动到页面底部为例。实现原理是分别获得当前滚动条的scrollTop值、当前可视范围的高度值clientHeight以及文档的总高度scrollHeight。当scrollTopclientHeight的值之和大于等于scrollHeight时,触发callback

    示例。查看链接:上拉加载demo

    <main>
        <ul id="refreshContainer">
            <li>111</li>
            <li>222</li>
            <li>333</li>
            <li>444</li>
            <li>555</li>
            ...
        </ul>
        <p class="refreshText"></p>
    </main>
    (function(window) {
        // 获取当前滚动条的位置 
        function getScrollTop() { 
            var scrollTop = 0; 
            if (document.documentElement && document.documentElement.scrollTop) { 
                scrollTop = document.documentElement.scrollTop; 
            } else if (document.body) { 
                scrollTop = document.body.scrollTop; 
            } 
            return scrollTop; 
        } 
    
        // 获取当前可视范围的高度 
        function getClientHeight() { 
            var clientHeight = 0; 
            if (document.body.clientHeight && document.documentElement.clientHeight) { 
                clientHeight = Math.min(document.body.clientHeight, document.documentElement.clientHeight); 
            } 
            else { 
                clientHeight = Math.max(document.body.clientHeight, document.documentElement.clientHeight); 
            } 
            return clientHeight; 
        } 
    
        // 获取文档完整的高度 
        function getScrollHeight() { 
            return Math.max(document.body.scrollHeight, document.documentElement.scrollHeight); 
        }
    
        var _text = document.querySelector('.refreshText'),
          _container = document.getElementById('refreshContainer');
    
        // 节流函数
        var throttle = function(method, context){
          clearTimeout(method.tId);
          method.tId = setTimeout(function(){
            method.call(context);
          }, 300);
        }
    
        function fetchData() {
            setTimeout(function() {
                _container.insertAdjacentHTML('beforeend', '<li>new add...</li>');
            }, 1000);
        }
    
        window.onscroll = function() {
          if (getScrollTop() + getClientHeight() == getScrollHeight()) {
              _text.innerText = '加载中...';
              throttle(fetchData);
          }
        };
    
    })(window);

    页面绑定onscroll事件时加入了节流函数,其作用就是忽略滚动条300毫秒内的连续多次触发。

    小结

    上拉刷新的实现主要依靠的是touch事件的三个阶段,以及借助CSS3动画效果;下拉加载主要依靠页面的onscroll事件,需要注意的是页面滚动时可能要考虑函数节流。

    转:https://www.cnblogs.com/zuobaiquan01/p/8874305.html

  • 相关阅读:
    CSS3 target伪类简介
    不用position,让div垂直居中
    css3 在线编辑工具 连兼容都写好了
    a标签伪类的顺序
    oncopy和onpaste
    【leetcode】1523. Count Odd Numbers in an Interval Range
    【leetcode】1518. Water Bottles
    【leetcode】1514. Path with Maximum Probability
    【leetcode】1513. Number of Substrings With Only 1s
    【leetcode】1512. Number of Good Pairs
  • 原文地址:https://www.cnblogs.com/fps2tao/p/9153909.html
Copyright © 2011-2022 走看看