通过监测滚动条实现无限滚动

本文的核心是检测滚动条的滑动:

  1.是否滚动到底部?

  2.上滚动还是下滚动?

怎样检测浏览器是否滚动到底部?

  需要检测3个值:scrollTop(滚动区顶部到可视区顶部的距离),clientHeight(可视区高度),scrollHeight(滚动区总高度),下图很好的解释了各自位置:

下面代码分别获取上述三个属性值:

1  var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;          
2   var clientHeight = document.documentElement.clientHeight;                
3   var scrollHeight = document.body.scrollHeight;

当这三个值获取到之后,通过下面代码计算差值来判断是否到底:

1 if (scrollTop >= scrollHeight - clientHeight ) {
2                    alert("到底!");  // 滚动到底部啦!!
3                     }

当然,实际应用中并不是滚动到底部才开始加载数据,这样就慢了一拍,常用的判断是快滚动到底部了就开始加载数据,那就设一个值吧,比如:离滚动条底部还差200px的时候就开始加载数据:

1 if (scrollTop >= bodyHeight - clientHeight  -  200 ) {
2                   
3                     alert("据底部200px");  // 离底部还有200px!赶紧加载新数据吧!
4                    
5                     }

上面就是滚动条检测的方法,其基本原理很简单,让哪个容器滚动就获取那个容器的scrollTop,clientHeight,scrollHeight即可,这里需要注意的是:在该容器的css代码中千万不要overflow:hidden;这样滚动条就不会出现了,overflow值要为auto或scroll。而我们要做的是无限滚动,也就是说在检测到底时添加新数据,公司代码一般会在此时发送ajax请求,本文后续的demo中就用插入新元素节点的方式代替吧。

怎样检测浏览器是上滚动还是下滚动?

  这里需要引入一个临时变量temp来保存scrollTop的值,其核心思想是:当滚动时scrollTop是时刻更新的,往下滚动scrollTop增加,网上滚动scrollTop减小,把scrollTop赋给临时变量temp,然后用最新的scrollTop值与temp(旧的scrollTop值)比较大小,大于temp则上滚动,否则下滚动:

 1   var temp = 0;
 2    window.onscroll=function (){    
 3    var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;        
 4    var clientHeight = document.documentElement.clientHeight;                
 5    var scrollHeight = document.body.scrollHeight;
 6         
 7         if (scrollTop <= temp) //起初只能下滚动,判断scrollTop小于则为向上滚动
 8                 { 
 9                     console.log("你在往上滚!");
10                 } 
11                 else 
12                 {
13                     console.log("你在往下滚!"); 
14                 }
15             temp = scrollTop; //最关键的一句代码,时刻更新temp的值
16     };

你看,原理就是这么简单。

实例效果

  下面用jquery来实现一个类似效果的demo(目前还是不知道博客园中怎么开通“运行代码”功能,所以先上代码吧):

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>无限滚动加载</title>
    <script type="text/javascript" src="./jquery-1.7.2.js"></script>
    <script type="text/javascript" src="./chajian.js"></script>
    <style type="text/css" rel="stylesheet">
    *{margin: 0;padding: 0;}  
    #main {background-color: green;height: 900px; margin: 0 auto; overflow: auto;  800px;}
    #message{ 250px; height:100px;background-color: orange;position: fixed;top:0px;left:1080px;font-size: 20px;text-align: center;}
    li { background-color: purple; 500px;height: 100px; margin-top: 10px;color: #fff;font-size: 40px;text-align: center; list-style: none;line-height: 100px;}
    </style>

<script type="text/javascript">
$(function () {
    var num = 10;//创建新li的序列号初始值
    var temp = 0;//为判断上下滚动设置的临时参考值

    $("#main").scroll(function () {

     var scrollTop = $(this).scrollTop();
     var clientHeight = $(this).height();
     var bodyHeight = $(this).prop("scrollHeight"); // 或$(this)[0].scrollHeight;或$(this).get(0).scrollHeight;

    if (scrollTop <= temp) //起初只能下滚动,判断scrollTop小于则为向上滚动
    { 
        $("#message").html("上滚动!<br> scrollTop:"+scrollTop+"px<br/>"+"temp:"+temp+"px");
    } 
    else 
    {
        $("#message").html("下滚动!<br> scrollTop:"+scrollTop+"px<br/>"+"temp:"+temp+"px");    
    }
    temp = scrollTop; //最关键的一句代码,时刻更新参考temp的值
    
    if (scrollTop >= bodyHeight - clientHeight-10 ) {
        //也可在此处设置延迟,让用户更清晰的感到加载的瞬间,但在IE下会出现多次加载的问题
        /*setTimeout(function () {
            longer();  
         }, 300);*/
        longer();
        }            
    });
    //滚动到底部时执行,创建新结点插入到ul中
    function longer() {
        for (var i = 0; i < 10; i++) {
            num++;  //更新li标签序号
            $("ul").append("<li>" + num + "</li>");                 
        }
    }       
})
</script>
</head>
<body>
<div id="message">滚动信息</div>
<div id="main">
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
        <li>7</li>
        <li>8</li>
        <li>9</li>
        <li>10</li>
    </ul>
</div>
</body>
</html>

封装成插件

  其实没必要封装成插件,这样做的目的只是为了练练手,毕竟自己还没写过像样的插件,想了一下,该插件就命名为scrollToBottom.js,用法为 $("XX").scrollToBottom(200 , function(){........})。第一个参数200为距离底部的距离,第二个参数就是到底部要执行函数,当然也可只传入一个函数作为参数,那就默认滚动条完完全全滚动到底部才执行函数。下面是scrollToBottom.js源码,很少很简单,见笑啦:

;(function($){  //ps: 为什么开头要加分号? 是防止代码压缩合并后因没有;而出错
    $.fn.extend({
        "scrollToBottom" : function(distance,fn){
                if(arguments.length === 1)
                {
                    fn = arguments[0]; 
                    distance = 0;
                }

                $(this).scroll(function(){
                var scrollTop = $(this).scrollTop();
                var clientHeight = $(this).height();
                var bodyHeight = $(this).prop("scrollHeight");
                
                if (scrollTop >= bodyHeight - clientHeight - distance){
                    fn&&fn();
                    }
                });    
        }
    });
})(jQuery)

引入插件,这样用起来就方便多了:

$("#main").scrollToBottom(200,function(){
          console.log("距离底部还有200px,想干什么就在这个函数里写吧!");
          //longer();
    }); 

专业插件推荐:jquery.nicescroll.js 

  nicescroll.js是款专业的滚动条插件,简单易用,对导航条进行了美化,缓冲减速,全屏等特效,用法为:

$('#main').niceScroll({
        cursorcolor:"orange", //控制滚动条颜色
        cursor"10" ,  //控制滚动条宽度,默认5px
        scrollspeed:90,   //滚动速度,默认60
        mousescrollstep: 40, //滚轮速度,默认40
        cursorborder: "2px solid red", //滚动条边框
        cursorborderradius:"15px",//圆角
        //touchbehavior:true, //拖拽主页滑动
        boxzoom:true //放大全屏
    });

关于此插件的详细用法请点击这里,英语不要太差哦 。

(完)

原文地址:https://www.cnblogs.com/chayangge/p/4251443.html