本文是实现网页底部加载新数据的小demo。
效果如图:
demo地址:demo
1、如何判断网页是否滑动到了底部?
如图,黑色区域为网页的真正长度,红色区域为用户可见区域(也就是浏览器所展现的趋于)。那么就得出了:scrollTop+windowHeight=srollHeight时,用户浏览到页面最底部。
作者:轨迹
我们只需要在用户浏览到最底部时,请求新数据即可。但是不是直接请求新数据,而是要在已读取的数据基础上,增添还未读取到的数据。本文使用的是偏移量来实现。
2、具体实现
通过前端记录并发送偏移量给后端,后端再根据偏移量查询数据并返回。
因为是个小demo,为了个人方便和展示方便,能写在一起的都写在一起了。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
<title></title>
<script type="text/javascript" src="js/jquery-3.2.1.js">
</script>
<script type="text/javascript">
var offset = 0;//偏移量
var nodata = false; //判断是否还有可读数据
var key = true ; //专门针对微信设置的key,否则在微信浏览器下数据会重复或错乱
$(document).ready(function() {
$(window).scroll(function() {
var scrollTop = $(this).scrollTop();
var scrollHeight = $(document).height();
var windowHeight = $(this).height();
//如果滚动到底部则获取数据
if(scrollTop + windowHeight >= scrollHeight && nodata==false && key==true) {
key = false;
$("#dialog").show();//提示正在加载
var url = "load.do";
var data = {
offset: offset + ''
};
$.post(url, data, function(data, status) {
if(data.arg0=="暂无数据"){
$("#ul").html($("#ul").html()+"<li>"+ data.arg0+"</li>");
nodata = true;
}else{
if(data.arg0!=null)
$("#ul").html($("#ul").html()+"<li>"+ data.arg0+"</li>");
if(data.arg1!=null)
$("#ul").html($("#ul").html()+"<li>"+ data.arg1+"</li>");
if(data.arg2!=null)
$("#ul").html($("#ul").html()+"<li>"+ data.arg2+"</li>");
if(data.arg3!=null)
$("#ul").html($("#ul").html()+"<li>"+ data.arg3+"</li>");
if(data.arg4!=null)
$("#ul").html($("#ul").html()+"<li>"+ data.arg4+"</li>");
offset = offset + 5;
}
$("#dialog").hide();
key = true;
});
}
});
});
</script>
<style type="text/css">
li {
height:50px;
width:100%;
display:block;
border:1px solid gray
}
ul{
margin:0 auto;
padding:0;
}
.dialog{
position: fixed;
bottom: 30px;
display: block;
width: 30%;
left: 35%;
border-radius: 5px;
height: 40px;
line-height: 40px;
background-color: #808080;
text-align: center;
color: white;
opacity: 0.7;
}
</style>
</head>
<body >
<div class="" style="width: 100%;height:800px;" id="div">
<ul id="ul">
<li>hello world!</li>
</ul>
</div>
<span class="dialog" id="dialog" hidden="true">
加载中...
</span>
</body>
</html>
@Controller
public class MyController {
@RequestMapping(value="/load")
public @ResponseBody Data loadNext(@RequestParam(value="offset",required=false) int offset){
ListData listData = new ListData();
listData.initData();//初始化数据
Data data = listData.getDataByOffset(offset);//通过偏移量获取数据
//判断是否还有可读数据
if(data==null) {
return new Data("暂无数据","","","","");
}
return data;
}
}
/**
* 伪数据库
* @author sam
*
*/
public class ListData {
//数据集合
private List<String> data = new ArrayList<String>();
/*
* 初始化(假)数据,假设是从数据库中查询到的。
*/
public void initData() {
for (int i = 0; i < 152; i++) {
data.add("这是第"+i+"条数据");
}
}
/*
* 从偏移的位置开始读取数据
*
* 这一步可以直接通过数据库 limit offset等操作完成!
*/
public Data getDataByOffset(int offset) {
//防止越界
if(data.size() - offset >= 5) {
//有>=5条的数据可读
String arg0 = data.get(offset);
String arg1 = data.get(offset+1);
String arg2 = data.get(offset+2);
String arg3 = data.get(offset+3);
String arg4 = data.get(offset+4);
return new Data(arg0,arg1,arg2,arg3,arg4);
}else if(offset < data.size() ){
//有1~4条的数据可读
int readable = data.size() - offset; //剩余可读条数
Data datas = new Data();
switch (readable) {
case 4: String arg3 = data.get(offset+3);
datas.setArg3(arg3);
case 3: String arg2 = data.get(offset+2);
datas.setArg2(arg2);
case 2: String arg1 = data.get(offset+1);
datas.setArg1(arg1);
case 1: String arg0 = data.get(offset);
datas.setArg0(arg0);
break;
default:
break;
}
return datas;
}
else {
//无数据可读
return null;
}
}
}
/**
* DTO
* @author xswift.轨迹
*
*/
public class Data {
private String arg0;
private String arg1;
private String arg2;
private String arg3;
private String arg4;
//省略getter、setter和构造器
}
3、遇到的问题
在电脑的chrome和手机uc都正常的情况下,使用微信浏览器会出现重复加载和漏加载的情况,所以在发送ajax时添加一个key,类似于临界区的访问。