微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

体验地址:

项目地址:

实现注意:

利用transition做动画时,优先使用transform:translate取代top,后者动画流畅度存在问题。

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

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

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

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

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

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

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

1)插件改为NPM包。

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

pullToRefresh.js:

rush:js;"> /** * 为指定的容器添加滚动条,支持下拉刷新与上拉加载功能 * @param container 需要滚动的容器,要求设置css: position!=static,height= * @param option 配置项,详见下方defaultOption说明 * @return 返回对象用于操控此区域,当前暴露了iscroll的refresh函数,当你在插件之外向滚动区域增加/删除内容后应该主动调用一次 * @description * * 2017-03-29 * 1)支持上拉加载 * 2017-03-30 * 1)改为jquery静态函数插件 * 2)支持关闭下拉刷新或上拉加载 */ $.installPullToRefresh = function (container,option) { // 起始触摸位置 var touchStartY = 0; // 起始图标位置 var pullStartY = 0; // 当前的触摸事件 var touchEvent = null; // 当前的刷新事件 var refreshEvent = null; // 当前图标位置 var curY = -55; // 当前的加载事件 var loadEvent = null; // 认参数 var defaultOption = { // 刷新相关 norefresh: false,// 关闭下拉刷新特性 pauseBound: 40,// 触发刷新的位置(也是图标loading暂停的位置) lowerBound: 80,// 最大下拉到多少px loadImg: "load.png",// loading图片 pullImg: "pull.png",// 下拉图片 onRefresh: function (refreshDone) { // 刷新数据回调 setTimeout(function() { // 认不做任何事 refreshDone(); },0); },// 加载相关 noLoad: false,// 关闭上拉加载特性 bottomHeight: 1,// 距离滚动条底部多少px发起刷新 onLoad: function (loadDone) { setTimeout(function() { loadDone(); },}; var finalOption = $.extend(true,defaultOption,option); // 创建iscroll5滚动区域 var iscroll = new IScroll(container,{ bounce: false,}); // 关闭上拉加载特性 if (!finalOption.noLoad) { // 监听滚动结束事件,用于上拉加载 iscroll.on('scrollEnd',function () { // 有滚动条的情况下,才允许上拉加载 if (iscroll.maxScrollY < 0) { // maxScrollY<0表明出现了滚动条 var bottomdistance = (iscroll.maxScrollY - iscroll.y) * -1; // 距离底部足够近,触发加载 if (bottomdistance <= finalOption.bottomHeight) { // 当前没有刷新和加载事件正在执行 if (!loadEvent && !refreshEvent) { loadEvent = {}; // 生成新的加载事件 finalOption.onLoad(function (error,msg) { loadEvent = null; // 清理当前的加载事件 // 延迟重绘滚动条 setTimeout(function () { iscroll.refresh(); },0); }); } } } }); } // 关闭下拉刷新特性 if (!finalOption.norefresh) { // 紧邻滚动区域,容纳刷新图标 var pullContainer = $('
') // 创建小图标 var pullToRefresh = $('
'); // 保留小图标的快捷方式 var pullImg = pullToRefresh.find("img"); // 小图标加入到容器 pullContainer.append(pullToRefresh); // 小图标容器添加到滚动区域之前 $(container).before(pullContainer); // 预加载loadImg $(' 1) { opcaticy = 1; } } // 改变位置和旋转角度 csstransform(pullToRefresh,"translateY(" + translateY + "px) translateZ(0)" + "rotateZ(" + rotate + "deg)"); // 改变透明度 pullToRefresh.css("opacity",opcaticy); } // 开启回弹动画 function tryStartBackTranTop() { // 启动回弹动画 pullToRefresh.addClass("backTranTop"); // 判断是否触发刷新 if (curY >= finalOption.pauseBound) { goTowards(finalOption.pauseBound); // 回弹动画结束发起刷新 pullToRefresh.on('transitionend webkittransitionend otransitionend',function (event) { // 由于transitionend会对每个属性回调一次,所以只处理其中一个 if (event.originalEvent.propertyName == "transform") { // 暂停动画 pullToRefresh.removeClass("backTranTop"); pullToRefresh.unbind(); // 透明度重置为1 goTowards(finalOption.pauseBound,undefined,1); // 切换图片为loading图 pullImg.attr("src",finalOption.loadImg); // 因为anamition会覆盖transform的原因,使用top临时定位元素 pullToRefresh.addClass("loadingAnimation"); pullToRefresh.css("top",finalOption.pauseBound + "px"); // 回调刷新数据,最终应将refreshEvent传回校验 finalOption.onRefresh(function (error,msg) { // 用户回调时DOM通常已经更新,需要通知iscroll调整(官方建议延迟执行,涉及到浏览器重绘问题) setTimeout(function () { iscroll.refresh(); },0); // 重置角度,切换为pull图 goTowards(finalOption.pauseBound); // 取消animation,重置top pullToRefresh.removeClass("loadingAnimation"); pullToRefresh.css("top",""); // 延迟过渡动画100毫秒,给浏览器重绘的机会 setTimeout(function () { // 切换为pull图 pullImg.attr("src",finalOption.pullImg); // 恢复动画 pullToRefresh.addClass("backTranTop"); // 刷新完成 refreshEvent = null; // 弹回顶部 goTowards(-55); },100); }); } }); } else { goTowards(-55); // 弹回顶部 refreshEvent = null; // 未达成刷新触发条件 } } // 父容器注册下拉事件 $(container).on("touchstart",function (event) { // 新的触摸事件 touchEvent = {}; // 有一个刷新事件正在进行 if (refreshEvent) { return; } // 只有滚动轴位置接近顶部,才可以生成新的刷新事件 if (iscroll.y < -1 * finalOption.lowerBound) { return; } // 一个新的刷新事件 refreshEvent = touchEvent; touchStartY = event.originalEvent.changedTouches[0].clientY; pullStartY = curY; // 如果存在,则关闭回弹动画与相关监听 pullToRefresh.removeClass("backTranTop"); pullToRefresh.unbind(); // 切换为pull图 pullImg.attr("src",finalOption.pullImg); }).on("touchmove",function (event) { // 在刷新未完成前触摸,将被忽略 if (touchEvent != refreshEvent) { return; } var touchCurY = event.originalEvent.changedTouches[0].clientY; var touchDistance = touchCurY - touchStartY; // 本次移动的距离 var curPullY = pullStartY + touchDistance; // 计算图标应该移动到的位置 // 向下不能拉出范围 if (curPullY > finalOption.lowerBound) { curPullY = finalOption.lowerBound; } // 向上不能拉出范围 if (curPullY <= -55) { curPullY = -55; } // 更新图标的位置 goTowards(curPullY); }).on("touchend",将被忽略 if (touchEvent != refreshEvent) { return; } // 尝试启动回弹动画 tryStartBackTranTop(); }); } // 初始化iscroll setTimeout(function() { iscroll.refresh(); },0); // 返回操作此区域的工具对象 return { // 用户如果在下拉刷新之外修改了滚动区域的内容,需要主动调用refresh refresh: function() { // 延迟以便配合浏览器重绘 setTimeout(function() { iscroll.refresh(); },// 触发下拉刷新 triggerPull: function() { // 正在刷新或者禁止刷新 if (refreshEvent || finalOption.norefresh) { return false; } // 暂停可能正在进行的最终阶段回弹动画 pullToRefresh.removeClass("backTranTop"); // 小图标移动到lowerbound位置 goTowards(finalOption.lowerBound); // 创建新的刷新事件,占坑可以阻止在setTimeout之前的触摸引起刷新 refreshEvent = {}; // 延迟到浏览器重绘 setTimeout(function() { tryStartBackTranTop(); },100); },}; }; Contact GitHub API Training Shop Blog About &copy; 2017 GitHub,Inc. Terms Privacy Security Status Help

pullToRefresh.css:

rush:js;"> .pullToRefresh { position:absolute; left:0; right:0; margin:auto; width: 50px; height: 50px; z-index: 10; opacity: 1; transform:translateY(-55px) translateZ(0) rotateZ(0deg); -ms-transform:translateY(-55px) translateZ(0) rotateZ(0deg); /* IE 9 */ -moz-transform:translateY(-55px) translateZ(0) rotateZ(0deg); /* Firefox */ -webkit-transform:translateY(-55px) translateZ(0) rotateZ(0deg); /* Safari 和 Chrome */ -o-transform:translateY(-55px) translateZ(0) rotateZ(0deg); /* Opera */ } .backTranTop { transition: transform 0.8s ease,opacity 0.8s ease; -moz-transition: transform 0.8s ease,opacity 0.8s ease; /* Firefox 4 */ -webkit-transition: transform 0.8s ease,opacity 0.8s ease; /* Safari 和 Chrome */ -o-transition: transform 0.8s ease,opacity 0.8s ease; /* Opera */ } .pullContainer { position:relative; } .pullToRefresh img { display:block; width: 40px; height: 40px; /* 让img居中在.pullToRefresh中 */ position: absolute; top: 0; bottom: 0; left:0; right:0; margin:auto; } /* loading旋转动画 */ .loadingAnimation { animation: loadingFrame 1s infinite; -moz-animation: loadingFrame 1s infinite; /* Firefox */ -webkit-animation: loadingFrame 1s infinite; /* Safari 和 Chrome */ -o-animation: loadingFrame 1s infinite; /* Opera */ } @keyframes loadingFrame { from { transform: rotateZ(360deg); } to { transform: rotateZ(0deg); } } @-moz-keyframes loadingFrame /* Firefox */ { from { transform: rotateZ(360deg); } to { transform: rotateZ(0deg); } } @-webkit-keyframes loadingFrame /* Safari 和 Chrome */ { from { transform: rotateZ(360deg); } to { transform: rotateZ(0deg); } } @-o-keyframes loadingFrame /* Opera */ { from { transform: rotateZ(360deg); } to { transform: rotateZ(0deg); } }

以上所述是小编给大家介绍的JS+CSS实现下拉刷新/上拉加载插件。编程之家 jb51.cc 收集整理的教程希望能对你有所帮助,如果觉得编程之家不错,可分享给好友!感谢支持

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐