下拉刷新示例

维护人:戴荔春 (6016)

说明

下拉刷新是移动项目开发中最常用的组件,框架中提供两大类的下拉刷新使用
一种类型是 项目默认下拉刷新 ,这种下拉刷新适合新人使用,往往结合这对应的接口规范使用
另一种类型是 基本的下拉刷新,里面只提供基础的下拉,上拉回调,以及关闭操作,其余业务逻辑完全由开发人员自定义
另外,框架内部默认提供多种下拉刷新的皮肤(外部调用方法都一致),丰富功能

目录

项目默认下拉刷新

目前项目有三种开发模式,第一种是纯跨平台开发,第二种是混合开发,第三种是普通网页开发

各大开发模式需要注意

父页面内容

父页面内容比较简单,只需要创建子页面即可
另外只有纯跨平台开发,并且采用default皮肤时才采用父页面,其余情况直接略过父页面这一步

//引入WindowTools
var WindowTools = require('WindowTools_Core');
//***其它逻辑
var PageArray = [{
	url: childPage, //下拉刷新内容页面地址
	id: childPage, //内容页面标志
	styles: {
		top: '45px', //内容页面顶部位置,需根据实际页面布局计算,若使用标准mui导航,顶部默认为48px;
		bottom: '0px' //其它参数定义
	}
}];
//使用框架生成子页面
WindowTools.createSubWins(PageArray);				
			

接口返回数据格式

默认的下拉刷新使用要求接口按照开发规范返回对应格式

{"ReturnInfo":{"Code":"1","Description":"对应的描述,code为1为正确,为0为错误.ReturnInfo 是程序的正确和错误判断"},"BusinessInfo":{"Code":"1","Description":"对应的描述,code为1为正确,为0为错误.BusinessInfo 是业务逻辑的正确和错误判断"},"UserArea":{"PageInfo":{"TotalNumCount":"总共消息的条数,整型"},"InfoList":[]}}

子页面内容

子页面的下拉刷新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);
});
			

调用说明

效果截图

采用几种不同皮肤的效果示例

基本的下拉刷新

基本的下拉刷新有三种皮肤,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
		});
	}
			

调用说明

注意要点

问题汇总

汇总框架下拉刷新使用时遇到的问题以及解决方法