维护人:戴荔春 (6016)
下拉刷新是移动项目开发中最常用的组件,框架中提供两大类的下拉刷新使用
一种类型是 项目默认下拉刷新 ,这种下拉刷新适合新人使用,往往结合这对应的接口规范使用
另一种类型是 基本的下拉刷新,里面只提供基础的下拉,上拉回调,以及关闭操作,其余业务逻辑完全由开发人员自定义
另外,框架内部默认提供多种下拉刷新的皮肤(外部调用方法都一致),丰富功能
目前项目有三种开发模式,第一种是纯跨平台开发,第二种是混合开发,第三种是普通网页开发
父页面内容比较简单,只需要创建子页面即可
另外只有纯跨平台开发,并且采用default皮肤时才采用父页面,其余情况直接略过父页面这一步
//引入WindowTools
var WindowTools = require('WindowTools_Core');
//***其它逻辑
var PageArray = [{
url: childPage, //下拉刷新内容页面地址
id: childPage, //内容页面标志
styles: {
top: '45px', //内容页面顶部位置,需根据实际页面布局计算,若使用标准mui导航,顶部默认为48px;
bottom: '0px' //其它参数定义
}
}];
//使用框架生成子页面
WindowTools.createSubWins(PageArray);
默认的下拉刷新使用要求接口按照开发规范返回对应格式
子页面的下拉刷新dom需要遵循固定格式
原理是因为除了Android下的mui默认实现,其它下拉刷新实现方法都是基于iScroll dom形式实现的
// <!--下拉刷新容器 dom结构 pullrefresh 和 listdata是下拉刷新组件默认的id 简单的调用没有必要修改,如果有自定义修改需求的,请参考详细调用 --> <div id="pullrefresh" class="mui-content mui-scroll-wrapper"> <div class="mui-scroll"> <!--数据列表--> <ul class="mui-table-view" id="listdata"> </ul> </div> </div>
简单的调用 (需要接口返回格式遵循开发规范)
//引入业务封装的下拉刷新
var PullToRefreshTools = require('PullToRefresh_Impl_Default_Core');
PullToRefreshTools.initPullDownRefresh({
isDebug: true,
bizlogic: {
//接口默认的初始页位置
defaultInitPageNum: 0,
//litemplate 为需要被映射的模板,例如<div id="{{id}}">{{name}}</div>
getLitemplate: litemplate,
//请求接口地址的url
getUrl: url,
//获取请求的参数,通过函数返回
getRequestDataCallback: getData,
//点击每一个列表中的li选项的回调
itemClickCallback: onClickCallback
},
//三种皮肤
//default -默认人的mui下拉刷新,webview优化了的
//type1 -自定义类别1的默认实现, 没有基于iscroll
//type1_material1 -自定义类别1的第一种材质
skin: 'default'
}, function(pullToRefresh) {
//console.log("生成下拉刷新成功");
//采用的异步生成,所以通过回调可以拿到下拉刷新对象
pullToRefreshObj = pullToRefresh;
setTimeout(function(){
//console.log("刷新");
//最一些事情,例如手动刷新一次请求
pullToRefreshObj.refresh();
},1000);
});
自定义的调用 (通过自定义传入回调,更加灵活的处理)
//引入业务封装的下拉刷新
var PullToRefreshTools = require('PullToRefresh_Impl_Default_Core');
PullToRefreshTools.initPullDownRefresh({
isDebug: true,
//下拉有关
down: {
height: 75,
contentdown: '下拉可以刷新', //可选,在下拉可刷新状态时,下拉刷新控件上显示的标题内容
contentover: '释放立即刷新', //可选,在释放可刷新状态时,下拉刷新控件上显示的标题内容
contentrefresh: '正在刷新', //可选,正在刷新状态时,下拉刷新控件上显示的标题内容
},
//上拉有关
//up为null代表不使用上拉加载更多
up: {
//是否自动上拉加载-初始化是是否自动
//这里不用这个来控制的话可以用下面的手动刷新
auto: false,
//距离底部高度(到达该高度即触发)
offset: 100,
//是否隐藏那个加载更多动画,达到默认加载效果
show: true,
contentdown: '上拉显示更多',
contentrefresh: '正在加载...',
contentnomore: '没有更多数据了',
},
bizlogic: {
//默认的请求页面,根据不同项目服务器配置而不同,正常来说应该是0
defaultInitPageNum: 0,
//得到模板 要求是一个函数(返回字符串) 或者字符串
//必须由外部传入
getLitemplate: litemplate,
//得到url 要求是一个函数(返回字符串) 或者字符串
//必须由外部传入
getUrl: url,
//得到请求参数 必须是一个函数,因为会根据不同的分页请求不同的数据,该函数的第一个参数是当前请求的页码
//必须由外部传入
getRequestDataCallback: getData,
//改变数据的函数,代表外部如何处理服务器端返回过来的数据
//如果没有传入,则采用内部默认的数据处理方法
changeResponseDataCallback: changeResponseDataCallback,
//改变最大数据量的函数
//如果是采用默认的数据处理,这个函数没有必要传,如果采用了自己的数据处理函数
//这是必须传的,否则数量永远为0,永远不能加载更多
changeToltalCountCallback: changeToltalCountCallback,
//请求成功,并且成功处理后会调用的成功回调方法,传入参数是成功处理后的数据
successRequestCallback: successRequestCallback,
//请求失败后的回调,可以自己处理逻辑,默认请求失败不做任何提示
errorRequestCallback: null,
//下拉刷新回调,这个回调主要是为了自动映射时进行数据处理
refreshCallback: null,
//列表点击回调,传入参数是 e,即目标对象
itemClickCallback: onClickCallback,
//的列表监听元素选择器,默认为给li标签添加标签
//如果包含#,则为给对应的id监听
//如果包含. 则为给class监听
//否则为给标签监听
targetListItemClickStr: 'li',
//默认的列表数据容器id,所有的数据都会添加到这个容器中,这里只接受id
listdataId: 'listdata',
//默认的下拉刷新容器id,mui会对这个id进行处理,这里只接受id
//注意,传给Mui时可以传 #id形式或者是 原生dom对象
pullrefreshId: 'pullrefresh',
//默认监听的刷新事件名称,通过触发这个事件即可刷新内容
//注意千万别是refresh,因为ios中Mui会默认触发一个refresh事件的
refreshEventName: 'refreshListPage',
//下拉刷新后的延迟访问时间,单位为毫秒
delyTime: 300,
//ajax请求有关的设置,包括accept,contentType等
ajaxSetting: {
//默认的请求超时时间
requestTimeOut: 15000,
//ajax的Accept,不同的项目中对于传入的Accept是有要求的
//传入参数,传null为使用默认值
/*示例
* {
* script: 'text/javascript, application/javascript, application/x-javascript',
* json: 'application/json;charset=utf-8'
* 等等(详情看源码)
* }
*/
accepts: {
script: 'text/javascript, application/javascript, application/x-javascript',
json: 'application/json',
xml: 'application/xml, text/xml',
html: 'text/html',
text: 'text/plain'
},
//默认的contentType
contentType: "application/x-www-form-urlencoded",
},
//是否请求完数据后就自动渲染到列表容器中,如果为false,则不会
//代表需要自己手动在成功回调中自定义渲染
isRendLitemplateAuto: true
},
//三种皮肤
//default -默认人的mui下拉刷新,webview优化了的
//type1 -自定义类别1的默认实现, 没有基于iscroll
//type1_material1 -自定义类别1的第一种材质
skin: 'default'
}, function(pullToRefresh) {
//console.log("生成下拉刷新成功");
pullToRefreshObj = pullToRefresh;
setTimeout(function() {
//console.log("刷新");
//这里通过手动刷新
pullToRefreshObj.refresh();
}, 1000);
});
手动刷新下拉刷新页面
pullToRefreshObj.refresh();
另外下拉刷新和上拉加载更多的开启和关闭由内部逻辑自行处理
更改下拉刷新文字位置
/*根据实际需求在父页面给mui-content设置top属性 */
.mui-bar-nav ~ .mui-content .mui-pull-top-pocket{
top: 180px !important;
}
采用几种不同皮肤的效果示例
默认下拉刷新
皮肤type1
皮肤type1_material1
基本的下拉刷新有三种皮肤,default,type1和 type1_material1
使用的要求仍然和封装业务的下拉刷新一样,如果是default皮肤,需要父子页面,dom结构要求也一致,只有代码调用有所差异
//下拉刷新基类
var pullToRefreshBase;
//下拉刷新对象
var pullToRefresh1;
/**
* @description 初始化时通过skin来决定使用哪一种下拉刷新
* 注意;初始化下拉刷新请在初始化时使用,重复使用无效
* 这里面是异步引入
* @param {String} skin
*/
function initPullToRefreshBySkin(skin) {
var generatePullToRefreshCallback = function(targetPullToRefresh) {
pullToRefreshBase = targetPullToRefresh;
initPullRefreshList();
};
if (skin === 'default') {
require.async('PullToRefresh_Base_Default_Core', generatePullToRefreshCallback);
} else {
//其它皮肤都需要引入css
CommonTools.importFile('css/RayApp/RayApp.PullToRefresh.css');
if (skin === 'type1') {
require.async('PullToRefresh_Base_Type1_Core', generatePullToRefreshCallback);
} else if (skin === 'type1_material1') {
require.async('PullToRefresh_Base_Type1__Material1_Core', generatePullToRefreshCallback);
} else {
console.error("错误:传入的下拉刷新皮肤错误,超出范围!");
}
}
}
/**
* @description 测试添加数据
* 真实情况添加的数据要根据接口返回数据映射
* @param {Number} count 数量
* @param {Boolean} isPullDown 是否是下拉刷新
*/
function testAppendData(count, isPullDown) {
isPullDown = isPullDown || false;
var fragment = document.createDocumentFragment();
var li;
for (var i = 0; i < count; i++) {
li = document.createElement('li');
li.className = 'mui-table-view-cell';
li.innerHTML = '测试item'+currpage+'-'+(i+1);
fragment.appendChild(li);
}
var dataContainer = document.getElementById('listdata');
//添加-下拉刷新时先清除数据
if (isPullDown) {
dataContainer.innerHTML = '';
}
dataContainer.appendChild(fragment);
}
/**
* @description 重置状态
* @param {Boolean} isPullDown 是否是上拉加载
*/
function resetState(isPullDown) {
if (isPullDown) {
pullToRefresh1.endPullDownToRefresh();
} else {
//上拉加载,判断当前页的数据是否已经大于totalCount
var itemLength = document.getElementById('listdata').children.length;
if (itemLength >= totalCount) {
pullToRefresh1.endPullUpToRefresh(true);
} else {
pullToRefresh1.endPullUpToRefresh(false);
}
}
}
/**
* @description 初始化下拉刷新
* 这时候,基类对象已经可以了
*/
function initPullRefreshList() {
var pullUpRefreshCallback1 = function() {
var self = this;
console.log("上拉加载");
setTimeout(function() {
//请求数据
//当前页++
currpage++;
//测试每次添加10条
testAppendData(10, false);
resetState(false);
}, 500);
};
var pullDownRefreshCallback1 = function() {
var self = this;
console.log("下拉刷新");
setTimeout(function() {
//下拉刷新当前页变为0
currpage = 0;
//测试每次添加10条
testAppendData(10, true);
resetState(true);
}, 1000);
};
var element = '#pullrefresh';
//初始化下拉刷新
pullToRefresh1 = pullToRefreshBase.initPullToRefresh({
//下拉有关
down: {
callback: pullDownRefreshCallback1,
},
//down为null表示不要下拉刷新
//down: null,
//上拉有关
up: {
//是否自动上拉加载-初始化是是否自动
auto: true,
//距离底部高度(到达该高度即触发)
offset: 100,
//是否隐藏那个加载更多动画,达到默认加载效果
show: true,
callback: pullUpRefreshCallback1
},
element: element
});
}
结束下拉刷新
pullToRefresh1.endPullDownToRefresh();
结束上拉加载更多
//传入参数为true代表没有更多数据,否则为可以加载更多 pullToRefresh1.endPullUpToRefresh(isNoMoreData);
更改下拉刷新文字位置
/*根据实际需求在父页面给mui-content设置top属性 */
.mui-bar-nav ~ .mui-content .mui-pull-top-pocket{
top: 180px !important;
}
下拉刷新是基于mui的再次封装,所以必须引入mui.min.js
项目默认的下拉刷新里面渲染数据用到了Mustache插件,所以必须引入Mustache.min.js
下拉刷新的dom结构必须和示例相同
汇总框架下拉刷新使用时遇到的问题以及解决方法
// <div id="pullrefresh" class="mui-content mui-scroll-wrapper"> <div class="common-input-row"> <div class="common-input common-search-container mui-search"> <span class="btn-search mui-icon mui-icon-search"id="searchBtn"></span> <input type="text" class="common-input-clear" placeholder="请输入搜索关键字" id="input-searchName"> </div> </div> <div class="mui-scroll"> <!--数据列表--> <ul class="mui-table-view" id="listdata"> </ul> </div> </div>
/*根据实际需求在父页面给mui-content设置top属性 */
.mui-bar-nav ~ .mui-content .mui-pull-top-pocket{
top: 180px !important;
}