在网上找了一大圈分页实现,没有找到,这个问题本来也一直想研究却拖了很久,于是就傻傻自己写了一套 JS。后来才发现其实好多前端框架的代码都是现成的。
参考了 LayUI 的分页风格,将 Bootstrap4 的分页完整地实现了出来。
代码如下,将头部引用的 jQuery 和 Bootstrap4 链接替换后可立即看到效果。

1 <!doctype html> 2 <html lang="en"> 3 <head> 4 <title>temp</title> 5 <link rel="stylesheet" href="../lib/bootstrap-4.3.1/bootstrap.min.css"> 6 <script src="../lib/jquery-3.4.1/jquery-3.4.1.js"></script> 7 <script src="../lib/bootstrap-4.3.1/bootstrap.min.js"></script> 8 </head> 9 <body> 10 <nav> 11 <ul id="pagination" class="pagination"> 12 <li class="page-item disabled"><a class="page-link" href="#">上一页</a></li> 13 <li class="page-item disabled"><a class="page-link" href="#">1</a></li> 14 <li class="page-item disabled"><a class="page-link" href="#">下一页</a></li> 15 </ul> 16 </nav> 17 </body> 18 <script> 19 let currPage = 1, // 当前页码 20 pageSize = 10; // 页大小 21 22 search(1); // 测试代码 23 24 // 向后端请求数据 25 function search(destPage) { 26 currPage = handlePage(destPage, currPage); 27 28 // 此处写 Ajax 向后端发送 currPage 和 pageSize 请求最大页码(和需要的业务数据) 29 let totalPage = 25; // 此处模拟返回的最大页码 30 31 $("#pagination").html(buildPagination(currPage, totalPage, 'search')); 32 } 33 34 35 36 /* 以下代码可放入公共 JS 文件以便服务各个需要分页的页面 */ 37 38 // 返回请求的目标页码 39 function handlePage(destPage, currPage) { 40 currPage = Number(currPage); 41 if (destPage === 'pre') { 42 currPage--; 43 } else if (destPage === 'next') { 44 currPage++; 45 } else { 46 currPage = destPage || 1; 47 } 48 return currPage; 49 } 50 // 构建翻页组件 51 function buildPagination(currPage, totalPage, funcName) { 52 currPage = Number(currPage); 53 totalPage = Number(totalPage); 54 let pageStr = ''; 55 if (totalPage > 1) { 56 if (totalPage <= 5) { 57 pageStr += prePage(currPage, funcName); 58 pageStr += startNPage(currPage, totalPage, funcName); 59 pageStr += nextPage(currPage, totalPage, funcName); 60 } else if (totalPage > 5) { 61 if (currPage < 5) { 62 pageStr += prePage(currPage, funcName); 63 pageStr += startNPage(currPage, totalPage, funcName); 64 pageStr += lastPage(totalPage, funcName); 65 pageStr += nextPage(currPage, totalPage, funcName); 66 } else { 67 if (currPage <= (totalPage - 5)) { 68 pageStr += prePage(currPage, funcName); 69 pageStr += firstPage(funcName); 70 pageStr += plusAndMinusTwoPages(currPage, funcName); 71 pageStr += lastPage(totalPage, funcName); 72 pageStr += nextPage(currPage, totalPage, funcName); 73 } else { 74 pageStr += prePage(currPage, funcName); 75 pageStr += firstPage(funcName); 76 pageStr += endNPage(currPage, totalPage, funcName); 77 pageStr += nextPage(currPage, totalPage, funcName); 78 } 79 } 80 } 81 } else { 82 pageStr += initPage(); 83 } 84 return pageStr; 85 } 86 // 初始状态 87 function initPage() { 88 return '<li class="page-item disabled"><a class="page-link" href="javascript: void(0);">上一页</a></li>' + 89 '<li class="page-item disabled"><a class="page-link" href="javascript: void(0);">1</a></li>' + 90 '<li class="page-item disabled"><a class="page-link" href="javascript: void(0);">下一页</a></li>'; 91 } 92 // 上一页 93 function prePage(currPage, funcName) { 94 let str = ''; 95 if (currPage === 1) { 96 str += '<li class="page-item disabled"><a class="page-link" href="javascript: void(0);">上一页</a></li>'; 97 } else { 98 str += '<li class="page-item"><a class="page-link" href="javascript: ' + funcName + '(\'pre\');">上一页</a></li>'; 99 } 100 return str; 101 } 102 // 固定首页 103 function firstPage(funcName) { 104 return '<li class="page-item"><a class="page-link" href="javascript: ' + funcName + '(1);">1</a></li>' + 105 '<li class="page-item disabled"><a class="page-link" href="javascript: void(0);">...</a></li>'; 106 } 107 // 开头的连续 n 页【注意判断总页数是否大于5】 108 function startNPage(currPage, totalPage, funcName) { 109 let str = '', total; 110 if (totalPage > 5) { 111 total = 5; 112 } else { 113 total = totalPage; 114 } 115 for (let i = 1; i < total + 1; i++) { 116 if (i === currPage) { 117 str += '<li class="page-item disabled"><a class="page-link" href="javascript: void(0);">' + i + '</a></li>'; 118 } else { 119 str += '<li class="page-item"><a class="page-link" href="javascript: ' + funcName + '(' + i + ');">' + i + '</a></li>'; 120 } 121 } 122 return str; 123 } 124 // 前后正负 2 页 125 function plusAndMinusTwoPages(currPage, funcName) { 126 let str = '', start = currPage - 2, end = currPage + 3; 127 for (let i = start; i < end; i++) { 128 if (i === currPage) { 129 str += '<li class="page-item disabled"><a class="page-link" href="javascript: void(0);">' + i + '</a></li>'; 130 } else { 131 str += '<li class="page-item"><a class="page-link" href="javascript: ' + funcName + '(' + i + ');">' + i + '</a></li>'; 132 } 133 } 134 return str; 135 } 136 // 末尾的连续 n 页 137 function endNPage(currPage, totalPage, funcName) { 138 let str = '', start = totalPage - 5 + 1, end = totalPage + 1; 139 for (let i = start; i < end; i++) { 140 if (i === currPage) { 141 str += '<li class="page-item disabled"><a class="page-link" href="javascript: void(0);">' + i + '</a></li>'; 142 } else { 143 str += '<li class="page-item"><a class="page-link" href="javascript: ' + funcName + '(' + i + ');">' + i + '</a></li>'; 144 } 145 } 146 return str; 147 } 148 // 固定末页 149 function lastPage(totalPage, funcName) { 150 return '<li class="page-item disabled"><a class="page-link" href="javascript: void(0);">...</a></li>' + 151 '<li class="page-item"><a class="page-link" href="javascript: ' + funcName + '(' + totalPage + ');">' + totalPage + '</a></li>'; 152 } 153 // 下一页 154 function nextPage(currPage, totalPage, funcName) { 155 let str = ''; 156 if (currPage === totalPage) { 157 str += '<li class="page-item disabled"><a class="page-link" href="javascript: void(0);">下一页</a></li>'; 158 } else { 159 str += '<li class="page-item"><a class="page-link" href="javascript: ' + funcName + '(\'next\');">下一页</a></li>'; 160 } 161 return str; 162 } 163 </script> 164 </html>
附:当总页数大于1时的设计思路分析
当 totalPage 小于等于 5 页时
【上一页】【开头的连续 n 页(n<=5)】【下一页】
当 totalPage 大于 5 页时
如果 currPage 小于 5
【上一页】【开头的连续 5 页】【……固定末页】【下一页】
如果 currPage 大于等于 5
如果 currPage 小于等于(totalPage - 5)
【上一页】【固定首页……】【前后正负 2 页】【……固定末页】【下一页】
如果 currPage 大于(totalPage - 5)
【上一页】【固定首页……】【末尾的连续 5 页】【下一页】