zoukankan      html  css  js  c++  java
  • JS实现-页面数据无限加载

    原文链接:  http://www.cnblogs.com/w-wanglei/p/5863387.html

    在手机端浏览网页时,经常使用一个功能,当我们浏览京东或者淘宝时,页面滑动到底部,我们看到数据自动加载到列表。之前并不知道这些功能是怎么实现的,于是自己在PC浏览器上模拟实现这样的功能。先看看浏览效果:

        当滚动条滚动到页面底部时,提示“正在加载…”。

    image

        当页面已经加载了所有数据后,滚动到页面底部会提示“数据已加载到底了”:

    image

        实现数据无限加载的过程大致如下:

        1.滚动条滚动到页面底部。

        2.触发ajax加载,把请求返回的数据加载到列表后面。

         如何判断滚动条是否滚动到页面底部?我们可以设置一个规则:当滚动条的滚动高度和整个文档高度相差不到20像素,则认为滚动条滚动到页面底部了:

        文档高度 - 视口高度 - 滚动条滚动高度 < 20

        要通过代码实现这样的判断,我们必须要了解上面的这些高度通过哪些代码获取?可以参考我之前写的一篇“HTML元素坐标定位,这些知识点得掌握”。

        上面的判断,我封装了一个方法:

    复制代码
    //检测滚动条是否滚动到页面底部
        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

  • 相关阅读:
    树莓派安装aria2轻松下载小资源
    利用树莓派3搭建可以发射无线局域网的微型服务器
    Vue语法
    redis-cluster集群
    分布式锁
    Redis--消息队列
    设计模式---享元模式
    设计模式(单例模式+原型模式)+ c#的内存分配机制
    MVC的ActionFilter
    MVC异常处理的7大场景 + MVC的异常处理的过滤器 + 全局异常
  • 原文地址:https://www.cnblogs.com/zhongshiqiang/p/5870940.html
Copyright © 2011-2022 走看看