一 mui原生下拉刷新及上拉加载
1 简述
为实现下拉刷新功能,大多数 H5 框架都是通过 DIV 模拟下拉回弹动画,在低端 android 手机上,DIV 动画经常出现卡顿现象(特别是图文列表的情况); mui 通过使用原生 webview 下拉刷新解决这个 DIV 动画的卡顿问题,并且拖动效果更加流畅。
但是,在wap网页中使用mui下拉刷新/上拉加载,只能使用DIV来实现mui的单 webview 模式/双 webview 模式,简而言之:单 webview 模式就是在同一个页面上完成加载;双 webview 模式就是在子页面完成拖动、加载列表整个流程,展示在父页面上(wap网页则是通过frame形式实现),此处推荐在wap网页中使用单webview模式。
2 实现流程
iOS平台的下拉刷新,使用的是 mui 封装的区域滚动组件, 为保证两个平台的 DOM 结构一致,内容页面需统一按照如下 DOM 结构构建:
<!--下拉刷新容器--><div id="refreshContainer" class="mui-content mui-scroll-wrapper"><div class="mui-scroll"><!--数据列表--><ul class="mui-table-view mui-table-view-chevron"></ul></div></div>
其次,在JS中通过 mui.init 方法中 pullRefresh 参数配置下拉刷新各项参数,如下:
mui.init({pullRefresh : {container:"#refreshContainer",//下拉刷新容器标识,querySelector能定位的css选择器均可,比如:id、.class等down : {height:50,//可选,默认50.触发下拉刷新拖动距离,auto: true,//可选,默认false.首次加载自动下拉刷新一次contentdown : "下拉可以刷新",//可选,在下拉可刷新状态时,下拉刷新控件上显示的标题内容contentover : "释放立即刷新",//可选,在释放可刷新状态时,下拉刷新控件上显示的标题内容contentrefresh : "正在刷新...",//可选,正在刷新状态时,下拉刷新控件上显示的标题内容callback :pullfresh-function //必选,刷新函数,根据具体业务来编写,比如通过ajax从服务器获取新数据;},up : {height:50,//可选.默认50.触发上拉加载拖动距离auto:true,//可选,默认false.自动上拉加载一次contentrefresh : "正在加载...",//可选,正在加载状态时,上拉加载控件上显示的标题内容contentnomore:'没有更多数据了',//可选,请求完毕若没有更多数据时显示的提醒内容;callback :pullfresh-function //必选,刷新函数,根据具体业务来编写,比如通过ajax从服务器获取新数据;}}});
3 加载的启动/禁用/结束触发
3-1.下拉刷新结束
在下拉刷新过程中,当获取新数据后,都需要执行 endPulldown 方法, 该方法的作用是关闭“正在刷新”的样式提示,内容区域回滚顶部位置,如下:
//在上面定义的下拉刷新触发的回调函数function pullfresh-function() {//业务逻辑代码,比如通过ajax从服务器获取新数据;......//注意,加载完新数据后,必须执行如下代码,注意:若为ajax请求,则需将如下代码放置在处理完ajax响应数据之后//没有更多内容了,endPulldown 传入true, 不再执行下拉刷新mui('#refreshContainer').pullRefresh().endPulldown();}
3-2.上拉加载结束/启用
和下拉刷新一样,上拉加载完新数据后,需要执行 endPullupToRefresh() 方法,结束转雪花进度条的“正在加载…”过程,enablePullupToRefresh(true|false) 传入true结束加载,为空或false时启用上拉加载。
如下:
function pullfresh-function() {//业务逻辑代码,比如通过ajax从服务器获取新数据;......//注意://1、加载完新数据后,必须执行如下代码,true表示没有更多数据了://2、若为ajax请求,则需将如下代码放置在处理完ajax响应数据之后//this.endPullupToRefresh(true|false);mui('#refreshContainer').pullRefresh().enablePullupToRefresh();}
3-3.上拉加载的重置
若部分业务中,有重新触发上拉加载的需求(比如当前类别已无更多数据,但切换到另外一个类别后,应支持继续上拉加载),此时调用 .refresh(true) 方法,可重置上拉加载控件,如下代码:
//注意:refresh()中需传入truemui('#refreshContainer').pullRefresh().refresh(true);
3-4.上拉加载的禁用
在部分场景下希望禁用上拉加载,比如在列表数据过少时,不想显示“上拉显示更多”、“没有更多数据”的提示语,开发者可以通过调用 disablePullupToRefresh() 方法实现类似需求,代码如下:
mui('#refreshContainer').pullRefresh().disablePullupToRefresh();
二 局部区域上拉加载
页面中存在多个模块,只在底部的模块中上拉刷新(触底时),加载更多数据
-HTML主要代码
<div class="moduleWrap"><div class="module"><p class="title">大家都在看</p><!-- 横向 --><div class="hengWrap" id="allheng"></div><!-- 间距 --><div class="spacing"></div><!-- 竖向 --><!--下拉刷新容器--><div id="pullrefresh"><!--数据列表--><div class="shuWrap" id="allshu"></div></div></div></div>
-js调用主要代码
mui.init({pullRefresh: {container: "#pullrefresh", //下拉刷新容器标识,querySelector能定位的css选择器均可,比如:id、.class等up: {style:'circle',//必选,下拉刷新样式,目前支持原生5+ ‘circle’ 样式//color:'#2BD009', //可选,默认“#2BD009” 下拉刷新控件颜色height: 50, //可选.默认50.触发上拉加载拖动距离auto: true, //可选,默认false.自动上拉加载一次contentrefresh: "正在加载...", //可选,正在加载状态时,上拉加载控件上显示的标题内容contentnomore: '没有更多数据了', //可选,请求完毕若没有更多数据时显示的提醒内容;callback: pullupRefresh //必选,刷新函数,根据具体业务来编写,比如通过ajax从服务器获取新数据;}},gestureConfig: {doubletap: true //双击事件默认是关闭}});var totalnum,countStop,scrollNum =3,count = 0;//初始化获取“大家都在看”的书籍长度mainapi('promote', {id:1004}, function(res) {totalnum =res.data.length;});/*** 上拉加载具体业务实现*/function pullupRefresh() {console.log('totalnum:'+totalnum);setTimeout(function() {countStop = totalnum ? parseInt(totalnum / 3) : 1;console.log("countStop:" + countStop +"num:" + count+" totalnum:"+totalnum);scrollNum += 3;everyData2();mui('#pullrefresh').pullRefresh().endPullupToRefresh((++count > countStop));//参数为true代表没有更多数据了。}, 1000);}if(mui.os.plus) {mui.plusReady(function() {setTimeout(function() {mui('#pullrefresh').pullRefresh().pullupLoading();}, 100);});} else {mui.ready(function() {mui('#pullrefresh').pullRefresh().pullupLoading();});}function everyData2() {var obj4 = {id: 1004,num: scrollNum}mainapi('promote', obj4, function(res) {var everbodyData = res.data;creatHengWrap("", "#allshu", everbodyData, 3);});}
三 同一页面中执行多个不同容器的下拉/上拉加载
截止到目前(Mui V3.7.2版本),mui的下拉/上拉加载仍是在同一页面中只支持单一页面的加载刷新执行,mui示例中给出了tab选项卡切换和多个相同上拉下拉加载的方案实例(点击查看)。
1 源码改造
综合网友分享经验,目前实现此需求,需要对mui.js的源码进行少量的修改,详细可参考mui.read.js查看2957行至3023行结合mui.js对比。修改逻辑大致如下(暂时不必深究):
mui.read.js
1-1.将源码中获取的pullRefresh对象(单个)改写为对象数组
1-2.使用for循环将对象数组中的元素赋值并执行定义的函数
2 js中调用
2-1.初始化时传入多个对象
mui初始化时,可传入一个或多个对象,分别定义样式及回调函数
/*初始化加载内容*/mui.init({pullRefresh: [{container: '#offCanvasContentScroll',down: {style:'circle',callback: pulldownRefresh},up: {style:'circle',height:0,contentrefresh: '上拉显示下一章...',contentnomore:'即将进入下一章',callback: pullupRefresh}},{container: '#offCanvasSideScroll',up: {style:'circle',//必选,下拉刷新样式,目前支持原生5+ ‘circle’ 样式//color:'#2BD009', //可选,默认“#2BD009” 下拉刷新控件颜色//height: 50, //可选.默认50.触发上拉加载拖动距离auto: true, //可选,默认false.自动上拉加载一次contentrefresh: "正在加载...", //可选,正在加载状态时,上拉加载控件上显示的标题内容contentnomore: '没有更多数据了', //可选,请求完毕若没有更多数据时显示的提醒内容;callback: pullupChapter //必选,刷新函数,根据具体业务来编写,比如通过ajax从服务器获取新数据;}}]});
2-2.分别定义回调函数
//上拉加载下一章function pullupRefresh() {//mui('#offCanvasContentScroll').pullRefresh().endPullupToRefresh();count2++;setTimeout(function() {//mui('#offCanvasContentScroll').pullRefresh().endPullupToRefresh(); //参数为true代表没有更多数据了。(count === 2)mui('#offCanvasContentScroll').pullRefresh().disablePullupToRefresh();//mui('#offCanvasContentScroll').pullRefresh().endPullupToRefresh();console.log(count2);if(count2 > 2){next();}else{return true;}}, 1500);}//下拉加载上一章function pulldownRefresh() {setTimeout(function() {prev();mui('#offCanvasContentScroll').pullRefresh().endPulldownToRefresh();}, 1500);}//上拉加载目录function pullupChapter() {setTimeout(function() {countStop = totalnum ? parseInt(totalnum / 50) : 1;num += 50;chapterList();mui('#offCanvasSideScroll').pullRefresh().endPullupToRefresh((++count > countStop)); //参数为true代表没有更多数据了。}, 1000);}
2-3.定义执行函数
定义回调函数中执行的函数,完毕
function next(){//跳转下一章}function prev(){//跳转上一章}function chapterList(){//ajax请求目录数据,绑定拼接}
四 同一页面中多次调用同一个上拉加载
备注:在切换调用上拉加载回调函数前,需要先调用 .refresh(true) 重置上拉加载控件
使用场景:比如在tab选项卡场景下,当前类别上拉加载已无更多数据,但点击切换到另外一个类别后,应支持继续上拉加载(此时需要重置上拉加载)
代码示例:仅为单个场景使用实例,并非所有的实现都需要按照这个逻辑流程
//点击不同tab切换分类function cateTab(val) {//执行函数……//调用了ajax加载方法everyData2();}//在定义上拉加载回调函数中,也会调用ajax请求方法function pullupRefresh() {setTimeout(function() {countStop = totalnum ? parseInt(totalnum / 6) : 1;//调用了ajax加载方法everyData2();scrollNum += 6;mui('#pullrefresh').pullRefresh().endPullupToRefresh((++count > countStop)); //参数为true代表没有更多数据了。(++count > countStop)}, 1000);}//因此在ajax加载方法函数中,调用.refresh(true)重置function everyData2() {//console.log('执行在这里');//mui('#bookList')[0].innerHTML = '';mui('#pullrefresh').pullRefresh().refresh(true);//mui.ajax()}
