JS實現-頁面數據無限加載

    在手機端瀏覽網頁時,常常使用一個功能,當咱們瀏覽京東或者淘寶時,頁面滑動到底部,咱們看到數據自動加載到列表。以前並不知道這些功能是怎麼實現的,因而本身在PC瀏覽器上模擬實現這樣的功能。先看看瀏覽效果:javascript

    當滾動條滾動到頁面底部時,提示「正在加載…」。css

image

    當頁面已經加載了全部數據後,滾動到頁面底部會提示「數據已加載到底了」:html

image

    實現數據無限加載的過程大體以下:java

    1.滾動條滾動到頁面底部。jquery

    2.觸發ajax加載,把請求返回的數據加載到列表後面。git

     如何判斷滾動條是否滾動到頁面底部?咱們能夠設置一個規則:當滾動條的滾動高度和整個文檔高度相差不到20像素,則認爲滾動條滾動到頁面底部了:github

    文檔高度 - 視口高度 - 滾動條滾動高度 < 20ajax

    要經過代碼實現這樣的判斷,咱們必需要了解上面的這些高度經過哪些代碼獲取?能夠參考我以前寫的一篇「HTML元素座標定位,這些知識點得掌握」。瀏覽器

    上面的判斷,我封裝了一個方法:session

//檢測滾動條是否滾動到頁面底部
    function isScrollToPageBottom(){
        //文檔高度
        var documentHeight = document.documentElement.offsetHeight;
        var viewPortHeight = getViewportSize().h;
        var scrollHeight = window.pageYOffset ||
                document.documentElement.scrollTop ||
                document.body.scrollTop || 0;

        return documentHeight - viewPortHeight - scrollHeight < 20;
    }

    判斷有了,咱們就能夠開啓一個定時器,900毫秒監測一次,若是isScrollToPageBottom()返回true則調用ajax請求數據,若是返回false則經過900毫秒以後再監測。

    下面是核心代碼實現:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>無限分頁</title>
    <link rel="stylesheet" href="assets/css/index.css"/>
</head>
<body>
<div class="l-page">
    <ul id="list" class="list">
    </ul>
</div>
<script src="//cdn.bootcss.com/jquery/3.1.0/jquery.min.js"></script>
<script src="js/jquery.mockjax.js"></script>
<script type="text/javascript" src="js/dataMock.js"></script>
<script type="text/javascript">
    //做爲一個對象的w和h屬性返回視口的尺寸
    function getViewportSize(w){
        //使用指定的窗口, 若是不帶參數則使用當前窗口
        w = w || window;

        //除了IE8及更早的版本之外,其餘瀏覽器都能用
        if(w.innerWidth != null)
            return {w: w.innerWidth, h: w.innerHeight};

        //對標準模式下的IE(或任意瀏覽器)
        var d = w.document;
        if(document.compatMode == "CSS1Compat")
            return {w: d.documentElement.clientWidth, h: d.documentElement.clientHeight};

        //對怪異模式下的瀏覽器
        return {w: d.body.clientWidth, h: d.body.clientHeight};
    }

    //檢測滾動條是否滾動到頁面底部
    function isScrollToPageBottom(){
        //文檔高度
        var documentHeight = document.documentElement.offsetHeight;
        var viewPortHeight = getViewportSize().h;
        var scrollHeight = window.pageYOffset ||
                document.documentElement.scrollTop ||
                document.body.scrollTop || 0;

        return documentHeight - viewPortHeight - scrollHeight < 20;
    }

    //商品模板
    function getGoodsTemplate(goods){
        return "<li>" +
                "<div class='pic-wrap leftFloat'>" +
                "<img src='" + goods.pic + "'>" +
                "</div>" +
                "<div class='info-wrap leftFloat'>" +
                "<div class='info-name'><span>" + goods.name + "</span></div>" +
                "<div class='info-address'><span>" + goods.address +"</span></div>" +
                "<div class='info-bottom'>" +
                "<div class='info-price leftFloat'><span>¥" + goods.price + "</span></div>" +
                "<div class='info-star leftFloat'><span>" + goods.star + "人推薦</span></div>" +
                "<div class='info-more leftFloat'><span>更多信息</span></div>" +
                "</div>" +
                "</div>" +
                "</li>";
    }

    //初始化的時候默給list加載100條數據
    $.ajax("http://localhost:8800/loadData?sessionId=" + (+ new Date)).done(function(result){
        if(result.status){
            var html = "";
            result.data.forEach(function(goods){
                html += getGoodsTemplate(goods);
            });
            $("#list").append(html);
        }
    });


    //加載數據
    function loadDataDynamic(){
        //先顯示正在加載中
        if( $("#loadingLi").length === 0)
             $("#list").append("<li id='loadingLi' class='loading'>正在加載...</li>");
        else{
            $("#loadingLi").text("正在加載...").removeClass("space");
        }
        var loadingLi = document.getElementById("loadingLi");
        loadingLi.scrollIntoView();
        //加載數據,數據加載完成後須要移除加載提示
        var hasData = false, msg = "";
        $.ajax("http://localhost:8800/loadData?sessionId=" + (+ new Date)).done(function(result){
             if(result.status){
                if(result.data.length > 0){
                    hasData = true;
                    var html = "";
                    result.data.forEach(function(goods){
                        html += getGoodsTemplate(goods);
                    });
                    $("#list").append(html);
                }else{
                    msg = "數據已加載到底了"
                }
            }
             $("#list").append(loadingLi);
        }).fail(function(){
            msg = "數據加載失敗!";
         }).always(function(){
            !hasData && setTimeout(function(){
                $(document.body).scrollTop(document.body.scrollTop -40);
            }, 500);
                msg && $("#loadingLi").text(msg);
            //從新監聽滾動
            setTimeout(watchScroll, 900);
         });
    }

    //若是滾動條滾動到頁面底部,須要加載新的數據,而且顯示加載提示
    function watchScroll(){
        if(!isScrollToPageBottom()){
            setTimeout( arguments.callee, 900);
            return;            }
        loadDataDynamic();
    }

    //開始檢測滾動條
    watchScroll();
</script>
</body>
</html>

    demo中ajax請求我是經過jquery-mockjax模擬的數據。代碼以下:

/**
 * 模擬接口.
 */
var i = 0, len = 200, addresses = ["四川", "北京", "上海", "廣州", "深圳", "甘肅", "雲南", "浙江", "青海", "貴州"];



function getData(){
    var size = Math.min(i + 50, len), arr = [];
    for(; i < size; i++){
        arr.push({
            name: "蘋果" + (i % 10 + 1),
            pic: "assets/images/iphone" + (i % 10 + 1) + ".jpg",
            price: parseInt(Math.random() * 10000),
            star: parseInt(Math.random() * 1000),
            address: addresses[i % 10]
        })
    }

    return arr;
}

$.mockjax({
    url: 'http://localhost:8800/loadData*',
    responseTime: 1000,
    response: function(settings){
        this.responseText = {
            status: true,
            data: getData()
        }
    }
});

    整個完整的demo我已上傳到github上:

    https://github.com/heavis/pageLoader

    在線演示:

    https://heavis.github.io/pageLoader/index.html

 

    若是本篇內容對你們有幫助,請點擊頁面右下角的關注。若是以爲很差,也歡迎拍磚。大家的評價就是博主的動力!下篇內容,敬請期待!

相關文章
相關標籤/搜索