JS + CSS实现下拉刷新/上拉加载插件

  

闲来无事,写了一个当下比较常见的下拉刷新/上拉加载的jquery插件,代码记录在这里,有兴趣将代码写成插件与npm包可以留言。

  

体验地址:http://owenliang.github.io/pullToRefresh/

  

项目地址:https://github.com/owenliang/pullToRefresh

  

  

利用过渡做动画时,优先使用变换:翻译取代,后者动画流畅度存在问题。

  

各移动浏览器对手势触摸的处理不同(简单罗列如下),但是下面的应对方案又会导致部分浏览器的溢出:滚动失效,总之难以兼容:

  

微信浏览器下拉自带回弹动画:可以禁止文档的touchmove事件默认处理行为。

  

谷歌浏览器下拉自带刷新功能:利用属性touch-action:没有可以禁掉。

  

针对上述问题,我的建议是滚动一律用iscroll5插件模拟实现(非溢出:滚动),然后利用上面的方法禁掉浏览器的默认touchmove行为。

  

过渡如果有多个属性,那么transitionend回调会为每个属性回调一次,因此遇到其中任意一个回调就应该把css和transitionend回调都删除掉。

  

浏览器在执行JS代码时没有机会重绘UI,因此在使用过渡的时候一定要注意把修改动画终止CSS的代码通过setTimeout延迟一会执行。

  

贴代码上首页,欢迎留言交流,需一位有兴趣有时间的朋友合作,主要做2件事:

  

1)插件改为NPM包。

  

2)基于pullToRefresh库,开发类似“今日头条”的左右滑动UI。

  

pullToRefresh.js:

     /* *   *为指定的容器添加滚动条,支持下拉刷新与上拉加载功能   * @param容器需要滚动的容器,要求设置css:位置!=静态,身高=* @param选择配置项,详见下方defaultOption说明   * @return返回对象用于操控此区域,当前暴露了iscroll的刷新函数,当你在插件之外向滚动区域增加/删除内容后应该主动调用一次   * @description   *   * 2017-03-29   * 1)支持上拉加载   * 2017-03-30   * 1)改为jquery静态函数插件   * 2)支持关闭下拉刷新或上拉加载   */美元。installPullToRefresh=函数(容器,选项){//起始触摸位置   var touchStartY=0;//起始图标位置   var pullStartY=0;//当前的触摸事件   var touchEvent=零;//当前的刷新事件   var refreshEvent=零;//当前图标位置   var卷曲=-55;//当前的加载事件   var loadEvent=零;//默认参数   var defaultOption={//刷新相关   noRefresh:假的,//关闭下拉刷新特性   pauseBound: 40,//触发刷新的位置(也是图标加载暂停的位置)   下界:80//最大下拉到多少px   loadImg:“负载。//加载png”,图片   pullImg:“拉。png”//下拉图片   祝辞& lt;/div>”)//创建小图标   var pullToRefresh=$ (' & lt; div类=皃ullToRefresh祝辞& lt; img src=" + finalOption。pullImg +”“祝辞& lt;/div>);//保留小图标的快捷方式   var pullImg=pullToRefresh.find (img);//小图标加入到容器   pullContainer.append (pullToRefresh);//小图标容器添加到滚动区域之前   $(容器).before (pullContainer);//预加载loadImg   $ (' & lt; img src=" + finalOption。loadImg +“祝辞');//设置变换的函数   函数cssTransform(节点、内容){   node.css ({   “-webkit-transform”:内容,   “-moz-transform”:内容,   “-ms-transform”:内容,   “-o-transform”:内容,   “转换”:内容,   });   }//调整小图标位置,角度,透明度   函数goTowards (translateY、旋转、opcaticy) {//更新当前小图标的位置,获取css(变换)比较麻烦,所以每次变更时自己保存   卷曲=translateY;//旋转图标(根据抵达下界的比例旋转,最大转1圈)   如果(旋转===定义){   旋转=(卷曲/finalOption.lowerBound) * 360;   }//透明度根据抵达pauseBound的比例计算   如果(opcaticy===定义){   opcaticy=(卷曲/finalOption.pauseBound) * 1;   如果(opcaticy比;1){   opcaticy=1;   }   }//改变位置和旋转角度   cssTransform (pullToRefresh“translateY (+ translateY +“px) translateZ (0)”+ " rotateZ(“+ +”旋转度)”);//改变透明度   pullToRefresh。css(“不透明度”,opcaticy);   }//开启回弹动画   函数tryStartBackTranTop () {//启动回弹动画   pullToRefresh.addClass (“backTranTop”);//判断是否触发刷新   如果(卷曲祝辞=finalOption.pauseBound) {   goTowards (finalOption.pauseBound);//回弹动画结束发起刷新   pullToRefresh。(“transitionend webkitTransitionEnd oTransitionEnd’,函数(事件){//由于transitionend会对每个属性回调一次,所以只处理其中一个   如果(event.originalEvent。propertyName==氨浠弧?{//暂停动画   pullToRefresh.removeClass (“backTranTop”);   pullToRefresh.unbind ();//透明度重置为1   goTowards (finalOption。pauseBound定义1);//切换图片为加载图   pullImg。attr (" src ", finalOption.loadImg);//因为anamition会覆盖变换的原因,使用前临时定位元素   pullToRefresh.addClass (“loadingAnimation”);   pullToRefresh。css(“顶级”,finalOption。pauseBound +“px”);//回调刷新数据,最终应将refreshEvent传回校验   finalOption。onRefresh(函数(错误,味精){//用户回调时DOM通常已经更新,需要通知iscroll调整(官方建议延迟执行,涉及到浏览器重绘问题)   setTimeout(函数(){   iscroll.refresh ();   }, 0);//重置角度,切换为拉图   goTowards (finalOption.pauseBound);//取消动画,重置   pullToRefresh.removeClass (“loadingAnimation”);   pullToRefresh。css(“顶级”、“”);//延迟过渡动画100毫秒,给浏览器重绘的机会   setTimeout(函数(){//切换为拉图   pullImg。attr (" src ", finalOption.pullImg);//恢复动画   pullToRefresh.addClass (“backTranTop”);//刷新完成   refreshEvent=零;//弹回顶部   goTowards (-55);   }, 100);   });   }   });   其他}{   goTowards (-55);//弹回顶部   refreshEvent=零;//未达成刷新触发条件   }   }//父容器注册下拉事件   美元(容器)。(“touchstart函数(事件){//新的触摸事件   touchEvent={};//有一个刷新事件正在进行   如果(refreshEvent) {   返回;   }//只有滚动轴位置接近顶部,才可以生成新的刷新事件   如果(iscroll。y & lt;1 * finalOption.lowerBound) {   返回;   }//一个新的刷新事件   refreshEvent=touchEvent;   touchStartY=event.originalEvent.changedTouches [0] .clientY;   pullStartY=卷曲;//如果存在,则关闭回弹动画与相关监听   pullToRefresh.removeClass (“backTranTop”);   pullToRefresh.unbind ();//切换为拉图   pullImg。attr (" src ", finalOption.pullImg);   })。(“touchmove函数(事件){//在刷新未完成前触摸,将被忽略   如果(touchEvent !=refreshEvent) {   返回;   }   var touchCurY=event.originalEvent.changedTouches [0] .clientY;   var touchDistance=touchCurY - touchStartY;//本次移动的距离   var curPullY=pullStartY + touchDistance;//计算图标应该移动到的位置//向下不能拉出范围   如果(curPullY比;finalOption.lowerBound) {   curPullY=finalOption.lowerBound;   }//向上不能拉出范围   如果(curPullY & lt;=-55) {   curPullY=-55;   }//更新图标的位置   goTowards (curPullY);   })。(“touchend函数(事件){//在刷新未完成前触摸,将被忽略   如果(touchEvent !=refreshEvent) {   返回;   }//尝试启动回弹动画   tryStartBackTranTop ();   });   }   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null

JS + CSS实现下拉刷新/上拉加载插件