上一篇给大家分享了《使用H5原生滚动的上拉加载功能》,但是没有下拉刷新的功能,今天赶快补上。
我们在上一篇中提到,因为iOS下mui中的下拉刷新插件,使用的是自绘的模拟滚动条,不是原生的,而上拉加载和下拉刷新的实现是一体的,因为HTML结构相互依赖,所以无法使用原生的上拉加载功能+mui的下拉刷新,来混合使用。
hello mui中的下拉刷新例子,使用的是新增数据插入头部的方式,这里我使用重新刷新的方式,当然两种情况都有各自使用的场景,请根据各自的需求来写。
功能特性
~原生实现,不依赖任何前端框架
~监听事件下拉刷新,segment+下拉刷新也可轻松支持
~代码轻量模块化
下一阶段功能
下拉刷新的时候列表底部会多出几十像素的小bug,暂不知什么原因,有高人解决了希望相告之
如何使用
1、html,结构与mui的上拉刷新基本一致,但是多了ios-content,因为使用的是区域滚动,来激活iOS的原生滚动
<!--下拉刷新容器 #content -->
<div id="content" class="ios-content mui-scroll-wrapper">
<div id="content_inner" class="mui-scroll">
<!--数据列表
<ul class="mui-table-view">
</ul>
-->
</div><!-- #content_inner -->
</div><!-- #content -->
2、css 使用div的区域滚动产生滚动条,同时新增mui-scroll的动画样式transitioning
.ios-content{
text-align: left;
width: 100%;
position: absolute;
top: 44px;
bottom: 0;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
.transitioning{
-webkit-transition: -webkit-transform 0.25s ease;
transition: transform 0.25s ease;
}
3、js 这里主要为了演示上拉加载,没有使用模板引擎,只是简单创建li元素
document.addEventListener('plusready', plus_ready, false);
var pulldown = null; // 定义全局的下拉刷新对象,ajax请求成功需要endPullDownToRefresh()
function plus_ready(){
// 初始化商品列表
get_goods_list();
// 下拉刷新
pulldown = pulldown_refresh({
container: '#content',
callback: get_goods_list
});
}
var last_length = 20;
function get_goods_list(){
// 模拟ajax加载网络数据
setTimeout(function(){
var table_node = document.createElement('ul');
table_node.setAttribute('class', 'mui-table-view');
for (var i = 0; i < 20; i++) {
var li = document.createElement('li');
li.className = 'mui-table-view-cell';
li.innerHTML = '<a class="mui-navigate-right">Item ' + (last_length-i) + '</a>';
table_node.appendChild(li);
}
// 兼容下拉刷新的情况,先清空节点后插入数据
var parent = document.getElementById("content_inner");
while(parent.firstChild)
parent.removeChild(parent.firstChild);
parent.appendChild(table_node);
// 下拉刷新的时候,区域收回,使用之前定义的全局变量
if(pulldown){
pulldown.endPullDownToRefresh();
}
last_length += 2;
}, 1000);
}
源代码
/**
* 下拉刷新类定义
*/
var PullDownRefresh = function(options){
this.container = options['container'];
this.callback = options['callback'];
this.is_draging = false;
this.start_delta_y = 0;
this.delta_y = 0;
};
PullDownRefresh.prototype = {
//可以在这里提供Person的基本功能
init : function(){
// 创建下拉可以刷新div
var div_node = document.createElement('div');
div_node.setAttribute('class', 'mui-pull-top-pocket mui-block mui-visibility');
var html = '<!--div class="mui-pull-top-pocket mui-block mui-visibility" style="-webkit-transform: translate3d(0px, -50px, 0px);"-->'+
' <div class="mui-pull">'+
' <div class="mui-pull-loading mui-icon mui-icon-pulldown" style="-webkit-transition: -webkit-transform 200ms ease; transition: -webkit-transform 200ms ease; -webkit-transform: rotate(0deg);"></div>'+
' <div class="mui-pull-caption">下拉可以刷新</div>'+
' </div>'+
'<!--/div-->';
div_node.innerHTML = html;
var parent = document.querySelector(this.container);
parent.insertBefore(div_node, parent.childNodes[0]);
// 设置初始位置
document.querySelector(this.container+" .mui-pull-top-pocket").style.webkitTransform = 'translate3d(0,-50px,0)';
document.querySelector(this.container+" .mui-scroll").style.webkitTransform = 'translate3d(0,0,0)';
var that = this;
document.querySelector(this.container).addEventListener('drag', function(e){
// 第一次滑动
if(!that.is_draging){
if(e.detail.direction === 'down'){
that.is_draging = true;
that.start_delta_y = e.detail.deltaY;
document.querySelector(that.container+" .mui-pull-top-pocket").style.webkitTransform = 'translate3d(0,-50px,0)';
document.querySelector(that.container+" .mui-pull-loading").setAttribute('class', 'mui-pull-loading mui-icon mui-icon-pulldown');
document.querySelector(that.container+" .mui-pull-top-pocket").classList.remove('transitioning');
document.querySelector(that.container+" .mui-scroll").classList.remove('transitioning');
}
}
if(that.is_draging){
if(e.detail.direction === 'down'){
e.stopPropagation();
that.delta_y = e.detail.deltaY - that.start_delta_y;
// 判断滑动距离,如果大于下拉加载区域的高,就翻转箭头
if(that.delta_y >= 100){
document.querySelector(that.container+" .mui-pull-caption").innerText = '释放立即刷新';
document.querySelector(that.container+" .mui-pull-loading").style.webkitTransform = 'rotate(-180deg)';
}else{
document.querySelector(that.container+" .mui-pull-caption").innerText = '下拉可以刷新';
document.querySelector(that.container+" .mui-pull-loading").style.webkitTransform = 'rotate(0deg)';
}
}
}
});
document.querySelector(this.container).addEventListener('dragend', function(e){
if(that.is_draging){
that.is_draging = false;
// 放开的时候,判断当前滚动条距离顶部滚动了多远, 如果没有往下拉,滚动条在下面,则return;
var scroll_top = document.querySelector(that.container).scrollTop;
if(scroll_top >= 0){
// 当在底部下拉滑动到顶部时,拖动距离可能超过100,始终保持文字为“下拉可以刷新”
document.querySelector(that.container+" .mui-pull-caption").innerText = '下拉可以刷新';
document.querySelector(that.container+" .mui-pull-loading").style.webkitTransform = 'rotate(0deg)';
return;
}
if(that.delta_y >= 100){
document.querySelector(that.container+" .mui-pull-caption").innerText = '努力加载中...';
document.querySelector(that.container+" .mui-pull-loading").setAttribute('class', 'mui-pull-loading mui-icon mui-spinner');
document.querySelector(that.container+" .mui-pull-top-pocket").style.webkitTransform = 'translate3d(0,0,0)';
document.querySelector(that.container+" .mui-scroll").style.webkitTransform = 'translate3d(0,50px,0)';
document.querySelector(that.container+" .mui-pull-top-pocket").classList.add('transitioning');
//TODO 有点小不足的地方,.mui-scroll加上动画后,在刷新后,底部会出现一块空白,再刷新又正常,循环往复
// 因为.mui-scroll延迟0.25s再滑上去,而框架没有缩回, 需要以后解决
document.querySelector(that.container+" .mui-scroll").classList.add('transitioning');
// callback
that.callback();
}
}
})
},
endPullDownToRefresh: function(){
document.querySelector(this.container+" .mui-pull-top-pocket").style.webkitTransform = 'translate3d(0,-50px,0)';
document.querySelector(this.container+" .mui-scroll").style.webkitTransform = 'translate3d(0,0,0)';
}
}
/**
* 上拉加载功能实现, 使用H5原生滚动
* @param {Array} options
* options: {
* container: '#content' // 容器
* callback: get_list_function // 下拉刷新业务逻辑
* }
* @author fanrong33
* @version 1.0.0 build 20150705
*/
var pulldown_refresh = function(options){
var obj = new PullDownRefresh(options);
obj.init();
return obj;
}