一、瀑布流分页案例分析
1.1) 功能分析:
鼠标下拉,加载分页数据(10条) ,如下图:
案例分析:
1.2) 如何确定当前显示的数据已经浏览完毕?
公式:(滚动条距底部的距离 + 滚动条上下滚动的距离 + 当前窗口的高度) >= 当前文档的高度
举例:
- 当前文档高度:存储10条数据,100px。
- 滚动条距底部的距离:1px。
- 当前窗口的高度:80px。
- 滚动条上下滚动的距离:>=19px。
因为文档高度不确定,不能只判断 滚动条上下滚动的距离大于等于19px。即要判断: 滚动条距底部的距离1px+当前窗口的高度80px +滚动条上下滚动的距离19px >=当前文档的高度。
1.3) 前置知识点:
$(function(){}) 页面加载事件
$(window) 获取当前窗口对象
scroll() 鼠标滚动事件
$(window).height() 当前窗口的高度
$(window).scrollTop() 滚动条上下滚动的距离
$(document).height() 当前文档高度
二、实现思路和代码
2.1)页面实现思路:
1. 定义发送请求标记。(控制是否发起请求,如果当前处于请求状态,就不能再去发请求,只有在请求完毕才能重新发起请求,类似于多线程里的等待唤醒机制)
2. 定义当前页码和每页显示的条数。 (分页必备的两个参数)
3. 定义滚动条距底部的距离。(可以设置固定值1就可以)
4. 设置页面加载事件。(事件里完成后续功能)
5. 为当前窗口绑定滚动条滚动事件。()
6. 获取必要信息(当前窗口的高度,滚动条上下滚动的距离,当前文档的高度)。
7. 计算当前展示数据是否浏览完毕。(浏览完毕需要发起请求)
8. 判断请求标记是否为 true。
9. 为true,将请求标记置为 false,当前异步操作完成前,不能重新发起请求。
10. 根据当前页和每页显示的条数来请求查询分页数据。
11. 当前页码+1。
页面和代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>网站首页</title>
<link rel="stylesheet" href="css/tt.css">
</head>
<body>
<div class="top">
<span class="top-left">下载APP</span>
<span class="top-left"> 北京 晴天</span>
<span class="top-right">更多产品</span>
</div>
<div class="container">
<div class="left">
<a>
<img src="img/logo.png"><br/>
</a>
<ul>
<li>
<a class="channel-item active" href="#">
<span>
推荐
</span>
</a>
</li>
<li><a class="channel-item" href="#">
<span>
视频
</span>
</a></li>
<li><a class="channel-item" href="#">
<span>
热点
</span>
</a></li>
<li><a class="channel-item" href="#">
<span>
直播
</span>
</a></li>
<li><a class="channel-item" href="#">
<span>
图片
</span>
</a></li>
<li><a class="channel-item" href="#">
<span>
娱乐
</span>
</a></li>
<li><a class="channel-item" href="#">
<span>
游戏
</span>
</a></li>
<li><a class="channel-item" href="#">
<span>
体育
</span>
</a></li>
</ul>
</div>
<div class="center">
<ul class="news_list">
<li>
<div class="title-box">
<a href="#" class="link">
这里是内容 !这里是内容 !这里是内容 !这里是内容 !这里是内容 !1
<hr>
</a>
</div>
</li>
<li>
<div class="title-box">
<a href="#" class="link">
这里是内容 !这里是内容 !这里是内容 !这里是内容 !这里是内容 !2
<hr>
</a>
</div>
</li>
<li>
<div class="title-box">
<a href="#" class="link">
这里是内容 !这里是内容 !这里是内容 !这里是内容 !这里是内容 !3
<hr>
</a>
</div>
</li>
<li>
<div class="title-box">
<a href="#" class="link">
这里是内容 !这里是内容 !这里是内容 !这里是内容 !这里是内容 !4
<hr>
</a>
</div>
</li>
<li>
<div class="title-box">
<a href="#" class="link">
这里是内容 !这里是内容 !这里是内容 !这里是内容 !这里是内容 !5
<hr>
</a>
</div>
</li>
<li>
<div class="title-box">
<a href="#" class="link">
这里是内容 !这里是内容 !这里是内容 !这里是内容 !这里是内容 !6
<hr>
</a>
</div>
</li>
<li>
<div class="title-box">
<a href="#" class="link">
这里是内容 !这里是内容 !这里是内容 !这里是内容 !这里是内容 !7
<hr>
</a>
</div>
</li>
<li>
<div class="title-box">
<a href="#" class="link">
这里是内容 !这里是内容 !这里是内容 !这里是内容 !这里是内容 !8
<hr>
</a>
</div>
</li>
<li>
<div class="title-box">
<a href="#" class="link">
这里是内容 !这里是内容 !这里是内容 !这里是内容 !这里是内容 !9
<hr>
</a>
</div>
</li>
<li>
<div class="title-box">
<a href="#" class="link">
这里是内容 !这里是内容 !这里是内容 !这里是内容 !这里是内容 !10
<hr>
</a>
</div>
</li>
</ul>
<div class="loading" style="text-align: center; height: 80px">
<img src="img/loading2.gif" height="100%">
</div>
<div class="content">
<div class="pagination-holder clearfix">
<div id="light-pagination" class="pagination"></div>
</div>
</div>
<div id="no" style="text-align: center;color: red;font-size: 20px"></div>
</div>
</div>
</body>
<script src="js/jquery-3.3.1.min.js"></script>
<script>
//1.定义发送请求标记
let send = true;
//2.定义当前页码和每页显示的条数
let start = 1;
let pageSize = 10;
//3.定义滚动条距底部的距离
let bottom = 1;//px
//4.设置页面加载事件
$(function () {
//5.为当前窗口绑定滚动条滚动事件
$(window).scroll(function () {
//6.获取必要信息,用于计算当前展示数据是否浏览完毕
//当前窗口的高度
let windowHeight = $(window).height();
//滚动条从上到下滚动距离
let scrollTop = $(window).scrollTop();
//当前文档的高度
let docHeight = $(document).height();
//7.计算当前展示数据是否浏览完毕
//当 滚动条距底部的距离 + 当前滚动条滚动的距离 + 当前窗口的高度 >= 当前文档的高度
if((bottom + scrollTop + windowHeight) >= docHeight) {
//8.判断请求标记是否为true
if(send == true) {
//9.将请求标记置为false,当前异步操作完成前,不能重新发起请求。
send = false;
//10.根据当前页和每页显示的条数来 请求查询分页数据
queryByPage(start,pageSize);
//11.当前页码+1
start++;
}
}
});
});
//定义查询分页数据的函数
function queryByPage(start,pageSize){
//加载动图显示
$(".loading").show();
//发起AJAX请求
$.ajax({
//请求的资源路径
url:"newsServlet",
//请求的参数
data:{"start":start,"pageSize":pageSize},
//请求的方式
type:"POST",
//响应数据形式
dataType:"json",
//请求成功后的回调函数
success:function (data) {
if(data.length == 0) {
$(".loading").hide();
$("#no").html("加载完毕...");
return;
}
//加载动图隐藏
$(".loading").hide();
//将数据显示
let titles = "";
for(let i = 0; i < data.length; i++) {
titles += "<li>\n" +
" <div class=\"title-box\">\n" +
" <a href=\"#\" class=\"link\">\n" +
data[i].title +
" <hr>\n" +
" </a>\n" +
" </div>\n" +
" </li>";
}
//显示到页面
$(".news_list").append(titles);
//将请求标记设置为true
send = true;
}
});
}
</script>
</html>
2.2)服务器实现思路:
1. 获取请求参数(当前页,每页显示的条数)。
2. 根据当前页码和每页显示的条数,调用业务层的方法,得到分页 Page 对象。
3. 将得到的数据转为 json。
4. 将数据响应给客户端。
服务器代码:
public class NewsServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求和响应的编码
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
//1.获取请求参数
String start = req.getParameter("start");
String pageSize = req.getParameter("pageSize");
//2.根据当前页码和每页显示的条数来调用业务层的查询方法,得到分页Page对象
Page page = service.pageQuery(Integer.parseInt(start), Integer.parseInt(pageSize));
//3.将得到的数据转为JSON
String json = new ObjectMapper().writeValueAsString(page);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//4.将数据响应给客户端
resp.getWriter().write(json);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
}
成功实现。