一 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()中需传入true
mui('#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()
}