背景:最近维护公司的一个老项目,其中就需要使用到分页功能。借鉴了网上一个有 bug 的分页组件,成功修复并实现了项目需求。
1.需求
Part1:
Part2:
Part3:
涉及:数据总条数展示、上一页、下一页、每页条数以及跳转页。
2.代码实现
1.html
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./css/common.css">
<link rel="stylesheet" href="./css/more.css">
<title>xxxxxx</title>
</head>
<body>
<!-- 页码 -->
<div class="page">
<div id="pp"></div>
</div>
</body>
<script src="./js/jquery-1.9.1.min.js"></script>
<script src="./js/page.js"></script>
<script>
$(document).ready(function () {
//分页器
$("#pp").cxPagination({
totalCount: 1000, //总页数
currentNumber: 1, //当前页
pageSize: 10, //默认每页条数
});
});
</script>
2.page.js
(function ($) {
$.fn.extend({
cxPagination: function (options) {
var obj = this;
if (!options) {
console.error("pagination options is undefined!");
return false;
}
if (options['totalCount'] == undefined) {
console.error(" totalCount in pagination options is undefined!");
return false;
}
var defaults = {
currentNumber: 1,
pageSize: 15,
pageSizeArr: [5, 10, 15, 20], //每页条数设置,可以通过在数组中自行添加确定可选每页条数
onSelectPage: function (pageNumber, pageSize) {
console.log("onSelectPage pageNumber: ");
console.log(pageNumber); // 当前页
console.log("pageSize: ");
console.log(pageSize); // 每页多少条数据
},
onChangePageSize: function (pageNumber, pageSize) {
console.log("onChangePageSize pageNumber: ");
console.log(pageNumber);
console.log("pageSize: ");
console.log(pageSize);
},
};
var settings = $.extend(defaults, options);
var onSelectPage = settings.onSelectPage;
var onChangePageSize = settings.onChangePageSize;
var pageSize = settings.pageSize;
var pageSizeArr = settings.pageSizeArr;
var totalCount = settings['totalCount'];
var currentNumber = settings['currentNumber'];
var totalPageNumber = parseInt(totalCount / pageSize); // 数据总条数/每页条数:一共有多少个分页页码
if (totalCount % pageSize > 0) {
totalPageNumber += 1;
}
if (totalCount <= 0) {
$(this).html("");
return;
}
if (currentNumber <= 0) {
currentNumber = 1;
}
// 当前页码大于10时,等于总分页页码(即最后一页),用于页码跳转
if (currentNumber > totalPageNumber) {
currentNumber = totalPageNumber;
}
// var startNumber = currentNumber - 2;
// var endNumber = currentNumber + 2;
var isFirstPage = (currentNumber == 1);
var isLastPage = (currentNumber == totalPageNumber); // 用于判断是否在最后一个分页页码中,来控制下一页按钮样式
// 数据总条数
var paginationHtml = '<nav aria-label="Page navigation">';
paginationHtml += '<ul class="pagination">';
// paginationHtml += '<li><span style="margin-right:5px;border:0;">共<span>' + totalPageNumber + "</span>页/" + totalCount + "条</span></li>";
paginationHtml += '<li class="total"><span>共<span>' + '<span class="total-num">' + totalCount + '</span>' + "条</span></li>";
// 判断是否是第一页,如果是就取消上一页点击按钮的样式
if (isFirstPage) {
paginationHtml += '<li><a href="javascript:void(0);" aria-label="Previous" style="cursor:default;pointer-events:none;color:#BFBFBF">'
+ '<span aria-hidden="true">上一页</span>'
+ '</a></li>';
}
else {
paginationHtml += '<li><a href="javascript:void(0);" aria-label="Previous">'
+ '<span aria-hidden="true">上一页</span>'
+ '</a></li>';
}
// 页码总数(按钮)
// 1.当总页码小于等于5时,加载所有页码
if (totalPageNumber > 0 && totalPageNumber <= 5) {
for (var i = 1; i <= totalPageNumber; i++) {
// 为当前页添加选中样式
if (i == currentNumber) {
paginationHtml += '<li><a class="active" href = "javascript:void(0);">' + i + '</a></li>';
} else {
paginationHtml += '<li><a href = "javascript:void(0);">' + i + '</a></li>';
}
}
// 2.当总页码大于5时,需要根据所选的当前页来动态生成页码
} else if (totalPageNumber > 5) {
// 2.1如果选中的当前页小于等于4,显示前面 1-5 页,后面显示省略号和尾页页码
if (currentNumber <= 4) {
for (var i = 1; i <= 5; i++) {
if (i == currentNumber) {
paginationHtml += '<li><a class="active" href = "javascript:void(0);">' + i + '</a></li>';
} else {
paginationHtml += '<li><a href = "javascript:void(0);">' + i + '</a></li>';
}
}
paginationHtml += '<li><a href="javascript:void(0);">...</a></li>'
+ '<li><a href="javascript:void(0);">' + totalPageNumber + '</a></li>'
// 2.2如果选中的当前页大于等于5且小于总页码-2,前面显示首页页码
} else if (currentNumber >= 5 && currentNumber < totalPageNumber - 2) {
paginationHtml += '<li><a href="javascript:void(0);">1</a></li>'
+ '<li><a href="javascript:void(0);">...</a></li>';
var startNum = Number(currentNumber) - 1
var endNum = Number(currentNumber) + 1
// console.log(typeof (Number(currentNumber)), 2222);
for (var i = startNum; i <= endNum; i++) {
if (i == currentNumber) {
paginationHtml += '<li><a class="active" href = "javascript:void(0);">' + i + '</a></li>';
} else {
paginationHtml += '<li><a href = "javascript:void(0);">' + i + '</a></li>';
}
}
paginationHtml += '<li><a href="javascript:void(0);">...</a></li>'
+ '<li><a href="javascript:void(0);">' + totalPageNumber + '</a></li>'
// 2.3如果选中的当前页大于等于总页码-2且小于等于总页码
} else if (currentNumber >= totalPageNumber - 2 && currentNumber <= totalPageNumber) {
paginationHtml += '<li><a href="javascript:void(0);">1</a></li>'
+ '<li><a href="javascript:void(0);">...</a></li>';
for (var i = totalPageNumber - 4; i <= totalPageNumber; i++) {
if (i == currentNumber) {
paginationHtml += '<li><a class="active" href = "javascript:void(0);">' + i + '</a></li>';
} else {
paginationHtml += '<li><a href = "javascript:void(0);">' + i + '</a></li>';
}
}
}
}
// 判断是否是最后一页,如果是就取消最后一页点击按钮的样式
if (isLastPage) {
paginationHtml += '<li><a href="javascript:void(0);" aria-label="Next" style="cursor:default;pointer-events:none;color:#BFBFBF">'
+ '<span aria-hidden="true">下一页</span>'
+ '</a></li>';
} else {
paginationHtml += '<li><a href="javascript:void(0);" aria-label="Next">'
+ '<span aria-hidden="true">下一页</span>'
+ '</a></li>';
}
paginationHtml += '<li><select>';
$.each(pageSizeArr, function (index, ele) {
if (ele == pageSize) {
paginationHtml += '<option selected value="' + ele + '">' + ele + '条/页</option>';
} else {
paginationHtml += '<option value="' + ele + '">' + ele + '条/页</option>';
}
});
paginationHtml += '</select></li>';
paginationHtml += '<li>前往<input class="to-page" id="pageNumberInput" value="' + currentNumber + '"/>页 '
+ '<button class="btn btn-default">确定</button></li>';
paginationHtml += '</ul></nav>';
$(this).html(paginationHtml);
$(this).find("li").on('click', function () {
var linkArr = $(this).find("a");
console.log(linkArr, 111111);
if (linkArr && linkArr.length > 0) {
var linkText = linkArr[0].innerText;
console.log(linkText, 2222);
//点击的是页码时
if (/^[0-9]+.?[0-9]*$/.test(linkText)) {//点击的是页数
//$(".pagination").find("li").removeClass("active");
// $(this).addClass("active");
currentNumber = linkText;
console.log(currentNumber, totalCount, pageSize, 333);
//页码 页大小改变时 重新加载渲染分页器
obj.cxPagination({
totalCount: totalCount,
currentNumber: currentNumber,
pageSize: pageSize
});
onSelectPage(currentNumber, pageSize);
} else {
var ariaLabel = linkArr[0].getAttribute("aria-label");
console.log("ariaLabel: " + ariaLabel);
//点击的是上一页或下一页按钮时
if (ariaLabel) {
if (ariaLabel == "Previous") {
currentNumber = currentNumber - 1;
//onSelectPage(currentNumber, pageSize);
} else if (ariaLabel == "Next") {
currentNumber = Number(currentNumber) + 1;
//onSelectPage(currentNumber, pageSize);
}
//页码 页大小改变时 重新加载渲染分页器
obj.cxPagination({
totalCount: totalCount,
currentNumber: currentNumber,
pageSize: pageSize
});
onSelectPage(currentNumber, pageSize);
}
}
}
});
//pageSize change事件
$(this).find("li>select").on('change', function (e) {
var newPageSize = e.target.value;
console.log("newPageSize: " + newPageSize);
pageSize = newPageSize;
//重新计算页数
totalPageNumber = parseInt(totalCount / pageSize);
if (totalCount % pageSize > 0) {
totalPageNumber += 1;
}
//$("#totalPageNumber").html(totalPageNumber);
if (currentNumber > totalPageNumber) {
currentNumber = totalPageNumber;
}
//页码 页大小改变时 重新加载渲染分页器
obj.cxPagination({
totalCount: totalCount,
currentNumber: currentNumber,
pageSize: pageSize
});
onChangePageSize(currentNumber, newPageSize);
});
//跳转页面点击事件
$(this).find("li>button").on('click', function (e) {
var newPageNumber = $("#pageNumberInput").val();
console.log("newPageNumber: " + newPageNumber);
if (newPageNumber == "" || newPageNumber == currentNumber) {
return false;
}
if (newPageNumber > totalPageNumber) {
newPageNumber = totalPageNumber;
}
currentNumber = newPageNumber;
//页码改变时 重新加载渲染分页器
obj.cxPagination({
totalCount: totalCount,
currentNumber: currentNumber,
pageSize: pageSize
});
onSelectPage(currentNumber, pageSize);
});
}
});
}(jQuery));
3.more.css
.page {
background: #F4F5F7;
}
.page #pp {
margin-bottom: 32px;
background-color: #f4f5f7;
}
.page #pp nav {
display: flex;
justify-content: flex-end;
align-items: center;
}
.page #pp nav ul {
list-style: none;
height: 36px;
line-height: 36px;
}
.page #pp nav ul li {
float: left;
}
.page #pp nav ul li a {
height: 36px;
line-height: 36px;
display: inline-block;
text-decoration: none;
color: #262626;
font-size: 14px;
padding: 0 14px;
border: 1px solid #D9DCE2;
margin-right: 8px;
border-radius: 4px;
background: #fff;
}
.page #pp nav ul li a.active {
border: 1px solid #368FFF;
color: #368FFF;
}
.page #pp nav ul li.total {
font-size: 14px;
color: #8C8C8C;
margin-right: 16px;
}
.page #pp nav ul li .total-num {
margin: auto 5px;
font-size: 14px;
color: #262626;
}
.page #pp nav ul li select {
float: left;
margin-left: 5px;
margin-right: 16px;
border: 1px solid #ddd;
height: 36px;
line-height: 36px;
border-radius: 4px;
}
.page #pp nav ul li .to-page {
width: 60px;
text-align: center;
border-radius: 4px;
border: 1px solid #D9DCE2;
margin: 0px 8px;
padding: 0 4px;
height: 36px;
line-height: 36px;
outline: none;
}
.page #pp nav ul li button {
cursor: pointer;
height: 36px;
padding: 4px 8px;
font-size: 14px;
margin-left: 5px;
background: #FFFFFF;
color: #262626;
border: 1px solid #D9DCE2;
padding: 8px 23px;
border-radius: 4px;
outline: none;
}
.page #pp nav ul li button:hover {
background: #368FFF;
color: #ffffff;
}
4.common.css
* {
box-sizing: border-box;
}
body,
div,
dl,
dt,
dd,
ul,
ol,
li,
h1,
h2,
h3,
h4,
h5,
h6,
pre,
code,
form,
fieldset,
legend,
input,
textarea,
p,
blockquote,
th,
td,
hr,
button,
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
margin: 0;
padding: 0;
}
body,
button,
input,
select,
textarea {
font-family: 'Microsoft YaHei', arial, SimSun, sans-serif, tahoma;
}
html,body {
width: 100%;
height: 100%;
background: #fff;
font-size: 16px;
-webkit-text-size-adjust: none;
}
input,
select,
textarea {
font-size: 100%;
}
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
display: block;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
fieldset,
img {
border: 0 none;
}
iframe {
display: block;
}
abbr,
acronym {
border: none;
font-variant: normal;
}
del {
text-decoration: line-through;
}
address,
caption,
cite,
code,
dfn,
em,
th,
var {
font-style: normal;
font-weight: 500;
}
ol,
ul {
list-style: none;
}
caption,
th {
text-align: left;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-size: 100%;
font-weight: 500;
}
q:before,
q:after {
content: '';
}
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
ins,
a {
text-decoration: none;
color: #000;
}
.clearfix:before,
.clearfix:after {
content: '';
display: table;
}
.clearfix:after {
clear: both;
overflow: hidden;
}
.clearfix {
zoom: 1;
}
.fl {
float: left;
}
.fr {
float: right;
}
.hidenone {
display: none;
visibility: hidden;
}
.hide {
visibility: hidden;
}
.mt10 {
margin-top: 10px;
}
.mt20 {
margin-top: 20px;
}
.ml10 {
margin-left: 10px;
}
.mr10 {
margin-right: 10px;
}
.pt10 {
padding-top: 10px;
}
.pl10 {
padding-left: 10px;
}
.pr10 {
padding-right: 10px;
}
.tc {
text-align: center;
}
.wd-1200 {
width: 1200px;
margin: 0 auto;
}
.wd-1200::after {
clear: both;
display: table;
content: '';
}
.pointer {
cursor: pointer;
}
.cl:after{
display:block;
clear:both;
content:"";
visibility:hidden;
height:0;
}
.nowrap {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}