前阶段作app H5页面html
有一个列表页须要下拉刷新上拉加载更多的需求,找到了Iscroll组件。看了相应的js,其实现这个功能的原理是监听滚动事件,利用滚动的方向,滚动的距离实现功能。以前用过的iscroll的逻辑大体是监听滚动的距离和5px作了一个比较,而后给固定的头部(内容为向下刷新)活底部(内容为上拉加载更多)添加或者移除相应的类,而后在经过判断头部或者底部是否存在这个类来进行的一个判断,从而触发刷新或者ajax请求加载更多。ajax
其实为了完成这个需求找过两版插件,可是初版出现了问题:当内容大于一屏的时候才能显现出来,当上拉的时候,屏幕并不能顺滑的向上滑动,并且在松开手以后内容老是定位到最上端,效果和里面内容设置了top:0同样。其实我就简单的试验了一下demo,后来出了bug在去试验demo的时候发现demo也有这个问题(囧)。json
后来又找了一个基于iscroll的dem,由于适合具体的业务相关,因此对其进行了实例化,下面贴出代码:app
//function pullWay(option) { var pageNo = 2; function Refresh() { setTimeout(function () { // <-- Simulate network congestion, remove setTimeout from production! var el, li, i; el = document.getElementById('thelist'); //这里写你的刷新代码 document.getElementById("wrapper").querySelector(".pullDownIcon").style.display = "none"; document.getElementById("wrapper").querySelector(".pullDownLabel").innerHTML = "<img src='../../images/ok.png'/>刷新成功"; setTimeout(function () { wrapper.refresh(); document.getElementById("wrapper").querySelector(".pullDownLabel").innerHTML = ""; }, 1000); //模拟qq下拉刷新显示成功效果 /****remember to refresh after action completed! ---yourId.refresh(); ----| ****/ }, 1000); } function Load() { setTimeout(function () { // <-- Simulate network congestion, remove setTimeout from production! var el, li, i; el = document.getElementById('thelist'); $.ajax({ type: "GET", url: option.url, data: { pageSize: 1, pageNo: pageNo++ }, dataType: "json", // contentType: 'application/json', success: function (data) { var html = option.ajaxWay(data); for (i = 0; i < 1; i++) { li = document.createElement('li'); li.innerHTML = html; el.appendChild(li, el.childNodes[0]); if (option.details) { option.details(); } wrapper.refresh(); // 数据加载完成后,调用界面更新方法 Remember to refresh when contents are loaded (ie: on ajax completion) } } }); }, 1000); // <-- Simulate network congestion, remove setTimeout from production! setTimeout(function(){ wrapper.refresh(); // 数据加载完成后,调用界面更新方法 Remember to refresh when contents are loaded (ie: on ajax completion) },3300) } var refresher = { info: { "pullDownLable": "下拉刷新", "pullingDownLable": "释放当即刷新", "pullUpLable": "上拉加载更多", "pullingUpLable": "释放加载更多", "loadingLable": "加载中..." }, init: function (parameter) { var wrapper = document.getElementById(parameter.id); var div = document.createElement("div"); div.className = "scroller"; wrapper.appendChild(div); var scroller = wrapper.querySelector(".scroller"); var list = wrapper.querySelector("#" + parameter.id + " ul"); scroller.insertBefore(list, scroller.childNodes[0]); var pullDown = document.createElement("div"); pullDown.className = "pullDown"; var loader = document.createElement("div"); loader.className = "pullDownIcon"; pullDown.appendChild(loader); var pullDownLabel = document.createElement("div"); pullDownLabel.className = "pullDownLabel"; pullDown.appendChild(pullDownLabel); scroller.insertBefore(pullDown, scroller.childNodes[0]); var pullUp = document.createElement("div"); pullUp.className = "pullUp"; var loader = document.createElement("div"); loader.className = "pullUpIcon"; pullUp.appendChild(loader); var pullUpLabel = document.createElement("div"); pullUpLabel.className = "pullUpLabel"; var content = document.createTextNode(refresher.info.pullUpLable); pullUpLabel.appendChild(content); pullUp.appendChild(pullUpLabel); scroller.appendChild(pullUp); var pullDownEle = wrapper.querySelector(".pullDown"); var pullDownOffset = pullDownEle.offsetHeight; var pullUpEle = wrapper.querySelector(".pullUp"); var pullUpOffset = pullUpEle.offsetHeight; this.scrollIt(parameter, pullDownEle, pullDownOffset, pullUpEle, pullUpOffset); }, scrollIt: function (parameter, pullDownEle, pullDownOffset, pullUpEle, pullUpOffset) { eval( parameter.id + "= new iScroll(\ parameter.id,\ {\ useTransition: true,\ vScrollbar: false,\ topOffset: pullDownOffset,\ onRefresh: function () {\ refresher.onRelease(pullDownEle,pullUpEle);\ },\ onScrollMove: function () {\ refresher.onScrolling(this,pullDownEle,pullUpEle,pullUpOffset);\ },\ onScrollEnd: function () {\ refresher.onScrollEnd(pullDownEle,parameter.pullDownAction,pullUpEle,parameter.pullUpAction);\ }\ })" ); }, onScrolling: function (e, pullDownEle, pullUpEle, pullUpOffset) { if (e.y > -(pullUpOffset) && !pullDownEle.className.match('loading')) { pullDownEle.classList.remove("flip"); pullDownEle.querySelector('.pullDownLabel').innerHTML = refresher.info.pullDownLable; pullDownEle.querySelector('.pullDownIcon').style.display = "block"; e.minScrollY = -pullUpOffset; } if (e.scrollerH < e.wrapperH && e.y > e.maxScrollY - pullUpOffset && pullUpEle.className.match("flip") || e.scrollerH > e.wrapperH && e.y > e.maxScrollY - pullUpOffset && pullUpEle.className.match("flip")) { pullUpEle.classList.remove("flip"); pullUpEle.querySelector('.pullUpLabel').innerHTML = refresher.info.pullUpLable; } if (e.y > 0 && !pullUpEle.className.match('loading') && !pullDownEle.className.match('loading')) { pullDownEle.classList.add("flip"); pullDownEle.querySelector('.pullDownLabel').innerHTML = refresher.info.pullingDownLable; e.minScrollY = 0; } if (e.scrollerH < e.wrapperH && e.y < (e.minScrollY - pullUpOffset) && !pullDownEle.className.match('loading') && !pullUpEle.className.match('loading') || e.scrollerH > e.wrapperH && e.y < (e.maxScrollY - pullUpOffset) && !pullDownEle.className.match('loading') && !pullUpEle.className.match('loading')) { pullUpEle.classList.add("flip"); pullUpEle.querySelector('.pullUpLabel').innerHTML = refresher.info.pullingUpLable; } }, onRelease: function (pullDownEle, pullUpEle) { if (pullDownEle.className.match('loading')) { pullDownEle.classList.toggle("loading"); pullDownEle.querySelector('.pullDownLabel').innerHTML = refresher.info.pullDownLable; } if (pullUpEle.className.match('loading')) { pullUpEle.classList.toggle("loading"); pullUpEle.querySelector('.pullUpLabel').innerHTML = refresher.info.pullUpLable; } }, onScrollEnd: function (pullDownEle, pullDownAction, pullUpEle, pullUpAction) { if (pullDownEle.className.match('flip') && !pullDownEle.className.match('loading')) { pullDownEle.classList.add("loading"); pullDownEle.classList.remove("flip"); pullDownEle.querySelector('.pullDownLabel').innerHTML = refresher.info.loadingLable; if (pullDownAction) pullDownAction(); } if (pullUpEle.className.match('flip') && !pullUpEle.className.match('loading')) { pullUpEle.classList.add("loading"); pullUpEle.classList.remove("flip"); pullUpEle.querySelector('.pullUpLabel').innerHTML = refresher.info.loadingLable; if (pullUpAction) pullUpAction(); } } } refresher.init({ id: "wrapper", //<------------------------------------------------------------------------------------┐ pullDownAction: Refresh, pullUpAction: Load });}原版的init函数,Refresh函数和Load函数不在这个js里面,为了作成一个统一的组件,将其封装在这个js里面,这样pullWay就是惟一的入口,传入相应的参数便可,你能够把page,ajax等在外部随意变化,最后当作参数传进来。对比一个以前的js,我作了一个比较,区别在于对于距离的选取更精确和更准确,并木有明确的数字,而是在触发事件的时候,对于相应的事件距离和容器距离进行获取和对比,从而进行下一步的判断和事件触发。实现的效果和官方demo的效果同样,符合如今大部分的下拉刷新上拉加载更多的需求,和原生的区别在于最下面的上拉加载更多的按钮不能在顶部定位,而是始终在内部内容的最下方。这个我后续会去找demo或者方法去优化,但愿这篇文章对你们有用,若是有什么不清楚的地方或者因为本身的项目形成的不适用,欢迎一块儿来讨论。