JS+CSS实现移动端下拉刷新
闲来无事,写了一个当下比较常见的下拉刷新/上拉加载的jquery插件,代码记录在这里,有兴趣将代码写成插件与npm包可以留言。
体验地址:http://owenliang.github.io/pullToRefresh/
项目地址:https://github.com/owenliang/pullToRefresh
实现注意:
- 利用transition做动画时,优先使用transform:translate取代top,后者动画流畅度存在问题。
- 各移动浏览器对手势触摸的处理不同(简单罗列如下),但是下面的应对方案又会导致部分浏览器的overflow:scroll失效,总之难以兼容:
- 微信浏览器下拉自带回弹动画:可以禁止document的touchmove事件默认处理行为。
- 谷歌浏览器下拉自带刷新功能:利用属性touch-action: none可以禁掉。
- 针对上述问题,我的建议是滚动一律用iscroll5插件模拟实现(非overflow:scroll),然后利用上面的方法禁掉浏览器的默认touchmove行为。
- transition如果有多个属性,那么transitionend回调会为每个属性回调一次,因此遇到其中任意一个回调就应该把css和transitionend回调都删除掉。
- 浏览器在执行JS代码时没有机会重绘UI,因此在使用transition的时候一定要注意把修改动画终止CSS的代码通过setTimeout延迟一会执行。
- 元素想垂直居中可以用position:absolute,然后通过top:0,bottom:0,margin:auto实现,相当于给绝对定位元素外面套了一个虚拟的父容器,top=0,bottom=0相当于父容器的尺寸。
- 动画方面利用transform的3D动画,可以触发浏览器使用硬件(GPU)加速,比如:使用transform:rotateZ,这样动画效果更流畅。
- 为了实现多点触摸,踩了半天的坑:
- 一开始希望在touchstart和touchend/touchcancel里通过changedTouches来追踪维护当前正在触屏的手指信息,经过真机调试日志发现ios和android都在复杂高频的多指操作情况下,部分手指的离开信息并没有通过changedtouches通知,简直坑死了。
- 为了克服这个问题,在touchstart里和touchend里总是与targetTouches进行全量的diff,因为targetTouches是当前正在触摸指定区域的手指列表,它是很准确的(比changedtouches这个增量的实现要靠谱的多),diff代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// 更新最新的手指集合 // 浏览器对changedTouches的实现存在问题, 因此总是使用全量的touches进行比对 function compareTouchFingers(event) { var identSet = {}; // 添加target内新出现的手指 for (var i = 0; i < event.originalEvent.targetTouches.length; ++i) { var touch = event.originalEvent.targetTouches[i]; identSet[touch.identifier] = true; if (touchFingers[touch.identifier] === undefined) { touchFingers[touch.identifier] = { clientY: touch.clientY, target: touch.target}; ++fingerCount; } } // 将target内消失的手指移除 for (var identifier in touchFingers) { // 与本次touchevent属于同一个target,但是touchevent中已消失的手指,需要移除 if (identSet[identifier] === undefined && touchFingers[identifier].target === event.originalEvent.target) { delete(touchFingers[identifier]); --fingerCount; } } } |
- 一定要处理touchcancel,当你正在触摸时如果来电话,或者把浏览器切换到后台,或者手指移动到了浏览器窗口外都有可能触发这个事件,如果发生这个事件那么touchend就不会触发了,因此写逻辑的时候直接把它俩视为等价即可。
如果文章帮助您解决了工作难题,您可以帮我点击屏幕上的任意广告,或者赞助少量费用来支持我的持续创作,谢谢~
