一、瀑布流分页案例分析
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); } }
成功实现。