jquery | 封装分页组件

377 阅读4分钟

背景:最近维护公司的一个老项目,其中就需要使用到分页功能。借鉴了网上一个有 bug 的分页组件,成功修复并实现了项目需求。

1.需求

Part1: 1.png Part2: 2.png Part3: 3.png

涉及:数据总条数展示、上一页、下一页、每页条数以及跳转页。

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;
}