HTML5实现全兼容的下拉刷新功能
前端一直有个技术有很少框架能够完美兼容,下拉刷新。自从ios提出这个功能后,很多设备上都在效仿,但是在h5上,有不少都是通过iscroll实现的,不过在低端安卓上略显卡顿。同时,iscroll体积的大小和button按钮的双点击bug也是让人苦不堪言。现在,我们就用最简单的方式来实现手机上全兼容的下拉刷新。
我们来看一个demo实例:http://cevio.github.io/simplizedemo/build/html/index.html#/components/lazyscroll
我们再来看下这个源码 : http://nap.webkits.cn/package/simplize-component-lazyscroll/lastest/src/js/main.js
下拉刷新最重要的点是window的touchmove和你下拉节点的touchmove之间的关系。
首先我们这么设定:
1 2 3 4 5 | window.addEventListener( 'touchmove' , function (e){ if ( window.cantouch ){ e.preventDefault(); } }); |
只要我们改变window.cantouch的值,那么我们就能让window默认滚动事件禁止。
同时我们通过对节点的touch事件监听来控制整个下拉过程。
源码中我们能看到这样的touchstart代码
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | 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。这里你可以做你自己的事情。我么使用
1 2 3 | function moveto(height){ this .style.webkitTransform = 'translate3d(0,' + height + 'px,0)' ; } |
来跟随moveY的距离通过css3来移动整个节点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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来写的。你们可以尝试下,效果体验一定能让你满意。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步