本文的核心是检测滚动条的滑动:
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 //放大全屏 });
关于此插件的详细用法请点击这里,英语不要太差哦 。
(完)