蔡繁荣
蔡繁荣
  • 发布:2015-07-05 15:26
  • 更新:2019-12-14 17:19
  • 阅读:13350

分享iOS平台使用H5原生滚动的下拉刷新功能v1.0.0 [不推荐]

分类:MUI

上一篇给大家分享了《使用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;  
}
6 关注 分享
豆花饭 后海 DCDDD kedou 远方的我 Trust

要回复文章请先登录注册

a***@gmail.com

a***@gmail.com

uni-app 没法用哇
2019-12-14 17:19
语嫣

语嫣

还是 mescroll 厉害 貌似后来者居上了 哈哈 都是大神
https://ask.dcloud.net.cn/article/529
2017-08-12 07:25
a***@sohu.com

a***@sohu.com

楼主,请问,如果想在“下拉可以刷新”的上面增加内容该如何增加?必须要用绝对定位吗?
2016-09-06 13:22
a***@sohu.com

a***@sohu.com

请问有人解决了刷新后底部有距离的BUG了吗,还望达人做出来分享一下这个BUG的解决办法呢。
2016-08-26 02:12
豆花饭

豆花饭

感谢分享~
2015-09-06 16:53
sjzhf

sjzhf

哦哦 这样啊
2015-07-08 17:10
蔡繁荣

蔡繁荣 (作者)

回复 sjzhf :
不是touchend无效,是因为iOS下使用的那个下拉回弹是用的系统原生的。
安卓滚动条是无法下拉下来的,很生硬的。
2015-07-08 17:05
sjzhf

sjzhf

回复 蔡繁荣 :
安卓 touchend无效吗
2015-07-08 17:03
蔡繁荣

蔡繁荣 (作者)

回复 sjzhf :
:( 目前该方案是使用iOS的原生滚动下拉回弹实现的,所以不支持安卓。下一阶段我会研究下通过双webview来实现下拉刷新,同时兼容iOS和Android。
2015-07-08 16:55
sjzhf

sjzhf

没有安卓吗
2015-07-08 16:47