原生app裡的數據列表都會使用下拉刷新的效果,在webapp裡可以采用iscroll、swiper等插件或框架實現,那麼如何自己編碼實現類似的效果呢,下面介紹使用原生js+css3實現的簡單效果。
html布局
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <title>test</title> <style type="text/css" media="screen"> body{margin: 0;} ul{list-style: none;padding: 0;} li{height: 30px;border-bottom: 1px solid #ddd;line-height: 30px;padding-left: 10px;} .scroller .loading{height: 60px;line-height: 60px;text-align: center;width: 100%;background-color: #f1f1f1;} .scroller{-webkit-overflow-scrolling:touch;} </style> </head> <body > <div id="container" class="scroller" > <div class="loading"> 下拉刷新數據 </div> <ul> <li><a href="#">列表數據1</a></li> <li><a href="#">列表數據2</a></li> <li><a href="#">列表數據3</a></li> <li><a href="#">列表數據4</a></li> <li><a href="#">列表數據5</a></li> <li><a href="#">列表數據6</a></li> <li><a href="#">列表數據7</a></li> <li><a href="#">列表數據8</a></li> <li><a href="#">列表數據9</a></li> <li><a href="#">列表數據10</a></li> <li><a href="#">列表數據11</a></li> <li><a href="#">列表數據12</a></li> <li><a href="#">列表數據13</a></li> <li><a href="#">列表數據14</a></li> <li><a href="#">列表數據15</a></li> <li><a href="#">列表數據16</a></li> <li><a href="#">列表數據17</a></li> <li><a href="#">列表數據18</a></li> <li><a href="#">列表數據19</a></li> <li><a href="#">列表數據20</a></li> <li><a href="#">列表數據21</a></li> <li><a href="#">列表數據22</a></li> <li><a href="#">列表數據23</a></li> <li><a href="#">列表數據24</a></li> <li><a href="#">列表數據25</a></li> <li><a href="#">列表數據26</a></li> <li><a href="#">列表數據27</a></li> <li><a href="#">列表數據28</a></li> <li><a href="#">列表數據29</a></li> <li><a href="#">列表數據30</a></li> </ul> </div> <body> </html>
js邏輯
var slide = function (option) { var defaults={ container:'', next:function(){} } var start, end, length, isLock = false,//是否鎖定整個操作 isCanDo = false,//是否移動滑塊 isTouchPad = (/hp-tablet/gi).test(navigator.appVersion), hasTouch = 'ontouchstart' in window && !isTouchPad; var obj = document.querySelector(option.container); var loading=obj.firstElementChild; var offset=loading.clientHeight; var objparent = obj.parentElement; /*操作方法*/ var fn = { //移動容器 translate: function (diff) { obj.style.webkitTransform='translate3d(0,'+diff+'px,0)'; obj.style.transform='translate3d(0,'+diff+'px,0)'; }, //設置效果時間 setTransition: function (time) { obj.style.webkitTransition='all '+time+'s'; obj.style.transition='all '+time+'s'; }, //返回到初始位置 back: function () { fn.translate(0 - offset); //標識操作完成 isLock = false; }, addEvent:function(element,event_name,event_fn){ if (element.addEventListener) { element.addEventListener(event_name, event_fn, false); } else if (element.attachEvent) { element.attachEvent('on' + event_name, event_fn); } else { element['on' + event_name] = event_fn; } } }; fn.translate(0-offset); fn.addEvent(obj,'touchstart',start); fn.addEvent(obj,'touchmove',move); fn.addEvent(obj,'touchend',end); fn.addEvent(obj,'mousedown',start) fn.addEvent(obj,'mousemove',move) fn.addEvent(obj,'mouseup',end) //滑動開始 function start(e) { if (objparent.scrollTop <= 0 && !isLock) { var even = typeof event == "undefined" ? e : event; //標識操作進行中 isLock = true; isCanDo = true; //保存當前鼠標Y坐標 start = hasTouch ? even.touches[0].pageY : even.pageY; //消除滑塊動畫時間 fn.setTransition(0); loading.innerHTML='下拉刷新數據'; } return false; } //滑動中 function move(e) { if (objparent.scrollTop <= 0 && isCanDo) { var even = typeof event == "undefined" ? e : event; //保存當前鼠標Y坐標 end = hasTouch ? even.touches[0].pageY : even.pageY; if (start < end) { even.preventDefault(); //消除滑塊動畫時間 fn.setTransition(0); //移動滑塊 if((end-start-offset)/2<=150) { length=(end - start - offset) / 2; fn.translate(length); } else { length+=0.3; fn.translate(length); } } } } //滑動結束 function end(e) { if (isCanDo) { isCanDo = false; //判斷滑動距離是否大於等於指定值 if (end - start >= offset) { //設置滑塊回彈時間 fn.setTransition(1); //保留提示部分 fn.translate(0); //執行回調函數 loading.innerHTML='正在刷新數據'; if (typeof option.next == "function") { option.next.call(fn, e); } } else { //返回初始狀態 fn.back(); } } } } slide({container:"#container",next: function (e) { //松手之後執行邏輯,ajax請求數據,數據返回後隱藏加載中提示 var that = this; setTimeout(function () { that.back.call(); }, 2000); }});
代碼不是很多,細節還需完善。