js實現『加載更多』功能實例

DEMO : 滾動加載示例css

關於如何實現『加載更多』功能,網上有插件可用,例如比較著名的使用iscroll.js實現的上拉加載更多、下拉刷新功能。html

但實際用起來倒是很麻煩。因爲是第三方插件,要按照對方定義的方法使用,用起來總感受很不順心。再加上iscroll.js自己並無集成加載更多的功能,須要進行自行擴展。想繼續使用iscroll.js實現加載更多功能的,上面給的連接能夠看看。git

h5項目裏須要實現簡單的分頁功能,因爲是移動端,考慮用『加載更多』會更好,而不是PC端的翻頁。github

基於按鈕實現加載更多

最簡單的就是給一個加載更多的按鈕,若是還有數據,點擊下加載更多,繼續拉幾條數據;直到沒有更多數據了,隱藏加載更多按鈕。ajax

DEMO : 基於按鈕實現加載更多json

這裏提早準備好數據。
演示數據格式:blog.jsonapp

{
    "list": [
        {
            "title": "這是title",
            "url": "http://www.cnblogs.com/52fhy/p/5271447.html",
            "desc": "摘要"
        },
        {
            "title": "這是title2",
            "url": "http://www.cnblogs.com/52fhy/p/4823390.html",
            "desc": "摘要"
        }]
}

頁面html:ide

<div class="content">
    <div class="weui_panel weui_panel_access">
        <div class="weui_panel_hd">文章列表</div>
        <div class="weui_panel_bd js-blog-list">
           
        </div>
    </div>
    
    <!--加載更多按鈕-->
    <div class="js-load-more">加載更多</div>
    
</div>
<script src="js/zepto.min.js"></script>

加載更多按鈕樣式:loadmore.css:函數

@charset "utf-8";

.js-load-more{
    padding:0 15px;
    width:120px;
    height:30px;
    background-color:#D31733;
    color:#fff;
    line-height:30px;
    text-align:center;
    border-radius:5px;
    margin:20px auto;
    border:0 none;
    font-size:16px;
    display:none;/*默認不顯示,ajax調用成功後才決定顯示與否*/
}

加載更多的js代碼:優化

$(function(){

    /*初始化*/
    var counter = 0; /*計數器*/
    var pageStart = 0; /*offset*/
    var pageSize = 4; /*size*/
    
    /*首次加載*/
    getData(pageStart, pageSize);
    
    /*監聽加載更多*/
    $(document).on('click', '.js-load-more', function(){
        counter ++;
        pageStart = counter * pageSize;
        
        getData(pageStart, pageSize);
    });
});

這裏的代碼並很少。其中getData(pageStart, pageSize)是業務邏輯代碼,負責從服務端拉去數據。這裏給個示例:

function getData(offset,size){
    $.ajax({
        type: 'GET',
        url: 'json/blog.json',
        dataType: 'json',
        success: function(reponse){
    
            var data = reponse.list;
            var sum = reponse.list.length;
    
            var result = '';
            
            /****業務邏輯塊:實現拼接html內容並append到頁面*********/
            
            //console.log(offset , size, sum);
            
            /*若是剩下的記錄數不夠分頁,就讓分頁數取剩下的記錄數
            * 例如分頁數是5,只剩2條,則只取2條
            *
            * 實際MySQL查詢時不寫這個不會有問題
            */
            if(sum - offset < size ){
                size = sum - offset;
            }
            
            /*使用for循環模擬SQL裏的limit(offset,size)*/
            for(var i=offset; i< (offset+size); i++){
                result +='<div class="weui_media_box weui_media_text">'+
                        '<a href="'+ data[i].url +'" target="_blank"><h4 class="weui_media_title">'+ data[i].title +'</h4></a>'+
                        '<p class="weui_media_desc">'+ data[i].desc +'</p>'+
                    '</div>';
            }
    
            $('.js-blog-list').append(result);
            
            /*******************************************/
    
            /*隱藏more按鈕*/
            if ( (offset + size) >= sum){
                $(".js-load-more").hide();
            }else{
                $(".js-load-more").show();
            }
        },
        error: function(xhr, type){
            alert('Ajax error!');
        }
    });
}

仍是比較簡單的。

基於滾動事件實現加載更多

上面咱們經過按鈕點擊實現加載更多,總體過程仍是比較簡單的。這裏,我提供另外一種方法實現加載更多:基於於滾動(scroll)事件。

DEMO : 基於滾動事件實現加載更多

直接貼代碼了:

$(function(){

    /*初始化*/
    var counter = 0; /*計數器*/
    var pageStart = 0; /*offset*/
    var pageSize = 7; /*size*/
    var isEnd = false;/*結束標誌*/
    
    /*首次加載*/
    getData(pageStart, pageSize);
    
    /*監聽加載更多*/  
    $(window).scroll(function(){
        if(isEnd == true){
            return;
        }

        // 當滾動到最底部以上100像素時, 加載新內容
        // 核心代碼
        if ($(document).height() - $(this).scrollTop() - $(this).height()<100){
            counter ++;
            pageStart = counter * pageSize;
            
            getData(pageStart, pageSize);
        }
    });
});

能夠看出,代碼變化不大,主要看核心代碼裏的判斷條件:當滾動到最底部以上100像素時, 加載新內容

業務邏輯getData(pageStart, pageSize)只須要把if ( (offset + size) >= sum)裏面的邏輯改爲:

if ( (offset + size) >= sum){
    isEnd = true;//沒有更多了
}

就好了。

固然,這裏面還有要優化的地方,例如:
如何防止滾動過快,服務端沒來得及響應形成屢次請求?

綜合實例

經過上面的例子,顯然第二種更好,不用去點擊。可是第二個方法有個問題:
若是設置頁面大小每次顯示2條或3條(size=2),總記錄是20,你會發現沒法觸發向下滾動加載更多的邏輯。這時候有個加載更多的點擊按鈕就行了。

所以,咱們能夠把以上兩種方法合在一塊兒:
默認使用滾動事件實現加載更多,當顯示數目過小不足以觸發向下滾動加載更多的邏輯時,使用加載更多點擊事件。

DEMO : 綜合實例

這裏,我對加載更多這個行爲進行簡單的抽象,寫了個簡單的插件:
loadmore.js

/*
 * loadmore.js
 * 加載更多
 *
 * @time 2016-4-18 17:40:25
 * @author 飛鴻影~
 * @email jiancaigege@163.com
 * 能夠傳的參數默認有:size,scroll 能夠自定義
 * */

;(function(w,$){
    
    var loadmore = { 
        /*單頁加載更多 通用方法
         * 
         * @param callback 回調方法
         * @param config 自定義參數
         * */
        get : function(callback, config){
            var config = config ? config : {}; /*防止未傳參數報錯*/

            var counter = 0; /*計數器*/
            var pageStart = 0;
            var pageSize = config.size ? config.size : 10;

            /*默認經過點擊加載更多*/
            $(document).on('click', '.js-load-more', function(){
                counter ++;
                pageStart = counter * pageSize;
                
                callback && callback(config, pageStart, pageSize);
            });
            
            /*經過自動監聽滾動事件加載更多,可選支持*/
            config.isEnd = false; /*結束標誌*/
            config.isAjax = false; /*防止滾動過快,服務端沒來得及響應形成屢次請求*/
            $(window).scroll(function(){
                
                /*是否開啓滾動加載*/
                if(!config.scroll){
                    return;
                }
                
                /*滾動加載時若是已經沒有更多的數據了、正在發生請求時,不能繼續進行*/
                if(config.isEnd == true || config.isAjax == true){
                    return;
                }
                
                /*當滾動到最底部以上100像素時, 加載新內容*/
                if ($(document).height() - $(this).scrollTop() - $(this).height()<100){
                    counter ++;
                    pageStart = counter * pageSize;
                    
                    callback && callback(config, pageStart, pageSize);
                }
            });

            /*第一次自動加載*/
            callback && callback(config, pageStart, pageSize);
        },
            
    }

    $.loadmore = loadmore;
})(window, window.jQuery || window.Zepto);

如何使用呢?很簡單:

$.loadmore.get(getData, {
    scroll: true,  //默認是false,是否支持滾動加載
    size:7,  //默認是10
    flag: 1, //自定義參數,可選,示例裏沒有用到
});

第一個參數是回調函數,即咱們的業務邏輯。我把最終修改過的業務邏輯方法貼出來:

function getData(config, offset,size){

    config.isAjax = true;

    $.ajax({
        type: 'GET',
        url: 'json/blog.json',
        dataType: 'json',
        success: function(reponse){
        
            config.isAjax = false;

            var data = reponse.list;
            var sum = reponse.list.length;
            
            var result = '';
            
            /************業務邏輯塊:實現拼接html內容並append到頁面*****************/
            
            //console.log(offset , size, sum);
            
            /*若是剩下的記錄數不夠分頁,就讓分頁數取剩下的記錄數
            * 例如分頁數是5,只剩2條,則只取2條
            *
            * 實際MySQL查詢時不寫這個
            */
            if(sum - offset < size ){
                size = sum - offset;
            }

            
            /*使用for循環模擬SQL裏的limit(offset,size)*/
            for(var i=offset; i< (offset+size); i++){
                result +='<div class="weui_media_box weui_media_text">'+
                        '<a href="'+ data[i].url +'" target="_blank"><h4 class="weui_media_title">'+ data[i].title +'</h4></a>'+
                        '<p class="weui_media_desc">'+ data[i].desc +'</p>'+
                    '</div>';
            }

            $('.js-blog-list').append(result);
            
            /*******************************************/
            
            /*隱藏more*/
            if ( (offset + size) >= sum){
                $(".js-load-more").hide();
                config.isEnd = true; /*中止滾動加載請求*/
                //提示沒有了
            }else{
                $(".js-load-more").show();
            }
        },
        error: function(xhr, type){
            alert('Ajax error!');
        }
    });
}

基本上與最初寫的是同樣的。

示例代碼託管在Github: https://github.com/52fhy/loadmore

-- 全文完 --

相關文章
相關標籤/搜索