前端一直有個技術有不多框架可以完美兼容,下拉刷新。自從ios提出這個功能後,不少設備上都在效仿,可是在h5上,有很多都是經過iscroll實現的,不過在低端安卓上略顯卡頓。同時,iscroll體積的大小和button按鈕的雙點擊bug也是讓人苦不堪言。如今,咱們就用最簡單的方式來實現手機上全兼容的下拉刷新。javascript
咱們來看一個demo實例:http://cevio.github.io/simplizedemo/build/html/index.html#/components/lazyscrollcss
咱們再來看下這個源碼 : http://nap.webkits.cn/package/simplize-component-lazyscroll/lastest/src/js/main.jshtml
下拉刷新最重要的點是window的touchmove和你下拉節點的touchmove之間的關係。前端
首先咱們這麼設定:vue
window.addEventListener('touchmove', function(e){ if ( window.cantouch ){ e.preventDefault(); } });
只要咱們改變window.cantouch的值,那麼咱們就能讓window默認滾動事件禁止。java
同時咱們經過對節點的touch事件監聽來控制整個下拉過程。ios
源碼中咱們能看到這樣的touchstart代碼css3
LazyScrollRefresh.prototype.touchEventStart = function(){ var that = this; return function(e){ if ( that.isRefreshing || that.getting ) { that.canMove = false; }else{ that.Vue.util.isAndroid && e.preventDefault(); that.canMove = true; that._y = e.targetTouches[0].pageY; that.y = 0; } } }
在手指觸碰到屏幕的時候,咱們canmove設定爲true。git
LazyScrollRefresh.prototype.touchEventMove = function(){ var that = this; return function(e){ if ( that.canMove && !that.getting ){ that.y = e.targetTouches[0].pageY; var moveY = that.y - that._y; if ( moveY > 0 && document.body.scrollTop <= 0 ){ that.soyie.windowTouchMoveDisabled = true; if ( moveY >= that.$options.refreshOffsetHeight ){ that.isRefreshing = true; moveto.call(this, that.slowSpeed(moveY)); that.$icon.classList.add('lazyscroll-rotate'); that.$title.innerHTML = that.$options.refresh.title; that.$value.innerHTML = that.$options.refresh.text; }else{ that.isRefreshing = false; moveto.call(this, moveY); that.$icon.classList.remove('lazyscroll-rotate'); that.$title.innerHTML = that.$options.defaults.title; that.$value.innerHTML = that.$options.defaults.text; } }else{ that.soyie.windowTouchMoveDisabled = false; that.isRefreshing = false; moveto.call(this, moveY); that.$icon.classList.remove('lazyscroll-rotate'); that.$title.innerHTML = that.$options.defaults.title; that.$value.innerHTML = that.$options.defaults.text; } } } }
在touchmove的時候,咱們禁止掉window的touchmove。不過須要注意的是,下拉刷新的條件是,你的_x於x的距離moveY必須>0,而且body的scrolltop必須<=0。這裏你能夠作你本身的事情。我麼使用github
function moveto(height){ this.style.webkitTransform = 'translate3d(0,' + height + 'px,0)'; }
來跟隨moveY的距離經過css3來移動整個節點。
LazyScrollRefresh.prototype.touchEventEnd = function(){ var that = this; return function(e){ if ( that.getting ) return; that.canMove = false; that._y = that.y = 0; that.soyie.windowTouchMoveDisabled = false; that.soyie.animationend(that.$root).then(function(){ if ( that.isRefreshing ){ if ( that.getting ) return; that.getting = true; that.$icon.innerHTML = that.$options.release.icon; that.$title.innerHTML = that.$options.release.title; that.$value.innerHTML = that.$options.release.text; that.emit('refreshing', that.next(that.$root)); }else{ (that.next())(); } }); that.$root.classList.add('layscroll-animate'); if ( that.isRefreshing ){ moveto.call(this, that.$options.refreshOffsetHeight); }else{ moveto.call(this, 0); } } }
在touchend的時候釋放window的touchmove事件,同時將canmove設置爲false,將全部用到的數據變量設置爲初始狀態。
基本邏輯就是這樣實現,你也能夠經過這個邏輯來實現一套更加完美的下拉刷新功能,不過這裏我推薦你們使用simplize來開發手機端的h5頁面。git項目地址是:
https://github.com/cevio/simplize
這套框架優點在於路由中間件在前端頁面的使用上。我麼能夠想express同樣操做前端的路由,很方便。頁面切換都幾乎接近來原生。不過底層的數據驅動是用vuejs來寫的。大家能夠嘗試下,效果體驗必定能讓你滿意。