Bootstrap

基于zepto的H5/移动端tab切换触摸拖动加载更多数据



以前实现移动端的滑动加载更多实现的方法是当滚动条快到页面底部时就自动加载更多的数据,在这方面很多人都用的是"西门的后花园"写的一个叫dropload的插件,这个插件用起来也很好,很感谢西门的后花园作者。我以前在项目中用的也是这个插件,后来我老大说能不能做成那种向上拖动才会加载更多的效果,不要这种滚动到底部就加载,于是我就使用了iscroll。
以下代码是加入了从数据库读取数据并判断数据全部加载完成的效果(事实是只模拟了从数据库读取数据,在使用时可将post请求的url和data换成你自己的就可以了),在本页的最后附上了模拟的代码可供下载查看。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>基于zepto的移动端/H5触摸拖动加载更多数据</title>
<style>
*{margin:0;padding:0;outline:0;-webkit-box-sizing:border-box;box-sizing:border-box;}
body{background:#f1f1f1;color:#666;}
li{list-style-type:none;}
a{text-decoration:none;color:#666;}
.tabsNav{overflow:hidden;padding:10px 15px;position:fixed;left:0;top:0;width:100%;z-index:2;background:#666;}
.tabsNav li{float:left;width:50%;text-align:center;height:30px;line-height:30px;font-size:14px;background:#f1f1f1;}
.tabsNav li.cur{background:#f00;color:#fff;}
.tabs_con{display:none;background:#fff;font-size:12px;}
.tabs_con li{height:40px;line-height:40px;border-bottom:1px solid #e9e9e9;padding-left:10px;}
#wrapper{position:absolute;z-index:1;top:45px;bottom:48px;width:100%;overflow:auto;}
#scroller{position:absolute;z-index:1;-webkit-tap-highlight-color:rgba(0,0,0,0);width:100%;}
#pullDown, #pullUp{height:40px;line-height:40px;font-size:12px;color:#888;text-align:center;}
#pullDown .pullDownIcon, #pullUp .pullUpIcon{position:absolute;margin:8px 0 0 30%;width:24px;height:24px;background:url(images/arrow.png) 0 0 no-repeat;
    -webkit-background-size:auto 100%;
    background-size:auto 100%;
    -webkit-transition-property:-webkit-transform;
    -webkit-transition-duration:250ms;
}
#pullDown .pullDownIcon{-webkit-transform:rotate(0deg) translateZ(0);}
#pullUp .pullUpIcon{-webkit-transform:rotate(-180deg) translateZ(0);}
#pullDown.flip .pullDownIcon{-webkit-transform:rotate(-180deg) translateZ(0);}
#pullUp.flip .pullUpIcon {-webkit-transform:rotate(0deg) translateZ(0);}
#pullDown.loading .pullDownIcon, #pullUp.loading .pullUpIcon{background-image: url(images/loader.png);background-size:100% auto;background-position:0 100%;
    -webkit-transform:rotate(0deg) translateZ(0);
    -webkit-transition-duration:0ms;
    -webkit-animation-name:loading;
    -webkit-animation-duration:2s;
    -webkit-animation-iteration-count:infinite;
    -webkit-animation-timing-function:linear;
}
@-webkit-keyframes loading {
    from{-webkit-transform:rotate(0deg) translateZ(0);}
    to{-webkit-transform:rotate(360deg) translateZ(0);}
}
</style>
</head>
<body>
<ul class="tabsNav">
    <li class="cur">公告</li>
    <li>消息</li>
</ul>
<div id="wrapper">          
    <div id="scroller">
        <div class="pullDown" id="pullDown">
            <div class="pullDownIcon"></div><div class="pullDownLabel">下拉刷新</div>
        </div>
        <div class="tabs_con" style="display:block;">
            <ul></ul>
        </div>      
        <div class="tabs_con">
            <ul></ul>
        </div>
        <div class="pullUp" id="pullUp">
            <div class="pullUpIcon"></div><div class="pullUpLabel">上拉加载更多</div>
        </div>
    </div>          
</div>
<input type="hidden" class="notice_hide">
<input type="hidden" class="msg_hide">
<script src="js/zepto.min.js"></script>
<script src="js/iscroll.js"></script>
<script>
    var pageNoticeIndex = 1,    //当前页
        pageMsgIndex = 1,
        pageSize = 5,   //每页数量
        load1More = false,   //判断是否全部加载完毕
        load2More = false;

    //tab切换
    $('.tabsNav li').on('click',function(){
        var $this = $(this);
        curIndex = $this.index();
        $this.addClass('cur').siblings('li').removeClass('cur');
        $('.tabs_con').eq(curIndex).css("display","block").siblings('.tabs_con').css("display","none");
        myScroll.scrollTo(0, 0);   //确保每次切换时scroll回到初始起点
        myScroll.refresh();        //每次切换时都要调用界面更新方法
        if(curIndex == 0){
            if(!load1More){
                $("#pullUp").html('<div class="pullUpIcon"></div><div class="pullUpLabel">上拉加载更多</div>');
            }else{
                $("#pullUp").html("已无更多数据");
            }
        }else if(curIndex == 1){
            if(!load2More){
                $("#pullUp").html('<div class="pullUpIcon"></div><div class="pullUpLabel">上拉加载更多</div>');
            }else{
                $("#pullUp").html("已无更多数据");
            }
        }
    }); 

    //公告
    pageNoitce(pageNoticeIndex, 0);    //初始化加载数据    第一个参数是当前页,第二个参数是当前选中的tab的索引
    function pageNoitce(pageIndex, curIndex) {
        var html = "";           
        $.post(url, data, function (success) {
            if (success != null && success.status == 1) {
                for (var i = 0; i < success.data.length; i++) {
                    html += '<li><a href="#">'+success.data[i].Title + '</a></li>';
                }

                var pageCount = parseInt(success.page.totRecord);
                var page = Math.ceil(pageCount / pageSize);
                if (page == pageIndex) {
                    load1More = true;
                }

                $(".tabs_con").eq(curIndex).children("ul").append(html);
            }
        }, "json");
    }

    //消息
    pageMsg(pageMsgIndex, 1);
    function pageMsg(pageIndex, curIndex) {
        var html = "";
        $.post(url, data, function (res) {
            if (res != null && res.status == 1) {
                for (var i = 0; i < res.data.length; i++) {
                    html += '<li><a href="#">' + res.data[i].Title + '</i></a></li>';                        
                }

                var pageCount = parseInt(res.page.totRecord);
                var page = Math.ceil(pageCount / pageSize);
                if (page == pageIndex) {
                    load2More = true;
                }

                $(".tabs_con").eq(curIndex).children("ul").append(html);
            }                        
        },"json");
    }


    var myScroll;   

    function pullDownAction () {
        setTimeout(function () {            
            myScroll.refresh();
        }, 1000);
    }

    function pullUpAction () {
        setTimeout(function () {
            var curIndex = $(".cur").index();
            if(curIndex == 0){
                if(!load1More){
                    pageNoticeIndex += 1;
                    $(".notice_hide").val(pageNoticeIndex);
                    pageNoitce($(".notice_hide").val(), curIndex);
                }else{
                    $("#pullUp").html("已无更多数据");
                }
                
            }else if(curIndex == 1){
                if(!load2More){
                    pageMsgIndex += 1;
                    $(".msg_hide").val(pageMsgIndex);   //确保每次切换回来还能接着上一次的数据继续加载更多,没有这个,那么切换回来的当前页pageIndex又要从1开始
                    pageMsg($(".msg_hide").val(), curIndex);
                }else{
                    $("#pullUp").html("已无更多数据");
                }
            }           
            myScroll.refresh();
        }, 1000);
    }

    function loaded() {
        var pullDownEl = $('#pullDown'),
            pullDownHeight = pullDownEl.height(),
            pullUpEl = $('#pullUp'),    
            pullUpHeight = pullUpEl.height(),
            pullDownLabel = $('.pullDownLabel'),
            pullUpLabel = $('.pullUpLabel');
        
        myScroll = new iScroll('wrapper', {
            topOffset: pullDownHeight - 5,
            onRefresh: function () {
                if (pullDownEl.hasClass('loading')) {
                    pullDownEl.removeClass();
                    pullDownLabel.html("下拉刷新");
                } else if (pullUpEl.hasClass('loading')) {
                    pullUpEl.removeClass();
                    pullUpLabel.html("上拉加载更多");
                }
            },
            onScrollMove: function () {
                if (this.y > 5 && !pullDownEl.hasClass('flip')) {
                    pullDownEl.removeClass().addClass('flip');
                    pullDownLabel.html("释放立即刷新");
                    this.minScrollY = 0;
                } else if (this.y < 5 && pullDownEl.hasClass('flip')) {
                    pullDownEl.removeClass();
                    pullDownLabel.html("下拉刷新");
                    this.minScrollY = -pullDownHeight;
                } else if (this.y < (this.maxScrollY - 5) && !pullUpEl.hasClass('flip')) {
                    pullUpEl.removeClass().addClass('flip');
                    pullUpLabel.html("释放加载更多");
                    this.maxScrollY = this.maxScrollY;
                } else if (this.y > (this.maxScrollY + 5) && pullUpEl.hasClass('flip')) {
                    pullUpEl.removeClass();
                    pullUpLabel.html("上拉加载更多");
                    this.maxScrollY = pullUpHeight;
                }
            },
            onScrollEnd: function () {
                if (pullDownEl.hasClass('flip')) {
                    pullDownEl.removeClass().addClass('loading');
                    pullDownLabel.html("加载中...");               
                    pullDownAction();
                } else if (pullUpEl.hasClass('flip')) {
                    pullUpEl.removeClass().addClass('loading');
                    pullUpLabel.html("加载中...");             
                    pullUpAction();
                }
            }
        });
    }

    document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
    document.addEventListener('DOMContentLoaded', function () { setTimeout(loaded, 200); }, false);
</script>
</body>
</html>

效果如下图:

;