zoukankan      html  css  js  c++  java
  • 移动端 上拉刷新,下拉加载 效果

    前言

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

    实现原理

    下拉刷新

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

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

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

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

    上拉加载

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

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

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<meta name="viewport" content="width=device-width, initial-scale=1">
    	<title>移动端上拉刷新、下拉加载</title>
    	<style type="text/css">
    		html,body,header,div,main,p,span,ul,li{ margin: 0; padding: 0; }
    		#refreshContainer li{ background-color: #eee; margin-bottom: 1px; padding: 20px 10px; }
    		.refreshText{ position: absolute;  100%; line-height: 50px; text-align: center; left: 0; top: 0; }
    		.bot_refreshText{ line-height: 50px; text-align: center; }
    	</style>
    </head>
    <body>
    <main>
    	<p class="refreshText"></p>
    	<ul id="refreshContainer">
    		<li>111</li>
    		<li>222</li>
    		<li>333</li>
    		<li>444</li>
    		<li>555</li>
    		<li>111</li>
    		<li>222</li>
    		<li>333</li>
    		<li>444</li>
    		<li>555</li>
    		<li>111</li>
    		<li>222</li>
    		<li>333</li>
    		<li>444</li>
    		<li>555</li>
    	</ul>
    	<p class="bot_refreshText"></p>
    </main>
    
    <!--上拉刷新-->
    <script type="text/javascript">
    	(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);
    </script>
    
    <!--下拉加载-->
    <script type="text/javascript">
    (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('.bot_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);
    </script>
    </body>
    </html>
    

      

    小结

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

  • 相关阅读:
    网络教程(2)光纤和RF编码简介
    网络教程(1)通过导线传播数字信号
    C语言基础 (11) 结构体 ,共用体 枚举 typedef
    C语言基础 (10) 变量作用域,生命周期 内存结构
    C语言基础 (9) 数组指针
    C语言基础 (8) 常用字符串处理函数
    C语言基础 (7) 输入输出
    短视频图像处理 OpenGL ES 实践
    短视频 SDK 6大功能技术实现方式详解
    从 HTTP 到 HTTPS 再到 HSTS
  • 原文地址:https://www.cnblogs.com/webdom/p/10599901.html
Copyright © 2011-2022 走看看