一、瀑布流分頁案例分析
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); } }
成功實現。