维护人:戴荔春 (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; }