More than a dozen lines of code teach you to encapsulate the front-end paging component based on bootstrap

Effect picture

Preface

Haha, I like to write a few words every time I write a blog. This was originally a front-end thing, but due to the need to do final works, a back-end student was forced to open business. Learn the full stack in advance

Paging logic description

1. Number buttons

There are always 7 number buttons. If the buttons on the left and right sides of the current page are sufficient, there are 3 buttons on the left and right sides. If there are less than 3 buttons to the left of the buttons on the current page, the range of the number button group is [1, 6]. If there are less than 3 buttons to the right of the buttons on the current page, the range of the number button group is [5, 11].

3. First page and last page

If the first page (the first page) appears in the 7 number buttons, there is no need to display the "First" button; similarly, if the page 11 (the last page) appears in the 7 number buttons, there is no need to display " "Last" button.

4. Previous page, next page

If there is no previous page (currently on page 1), the "Pre" button is not displayed; if there is no next page (the current page is on the last page), there is no need to display the "Next" button.

Code

The logic seems a bit complicated. Coding ideas must be clear, otherwise it may be uncomfortable to write because of more details, lengthy and more or less small bugs.

The following code has detailed comments and an introduction to coding ideas. Remove the comment, the key code is no more than ten or twenty lines.

The introduction of bootstrap, slightly...

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <!-- 不设置的话,手机端不会进行响应式布局 -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>商品列表页</title>

    <!-- 引入Bootstrap核心样式文件 -->
    <link rel="stylesheet" href="lib/bootstrap4/css/bootstrap.css">


    <style>
        /* 分页按钮样式复写 */
        /*.page-link {*/
        /*    color: #8c8c8c;*/
        /*}*/
        /*.page-link:hover {*/
        /*    color: #007bff;*/
        /*}*/
    </style>

    <!--站点图标-->
    <!-- ... -->

</head>
<body>

    <div class="page-helper mt-5 d-flex justify-content-center">

    </div>

    <!-- js的顺序不能乱 -->
    <script src="lib/jquery/jquery.min.js"></script>
    <!-- bootstrap.min.js依赖jquery -->
    <script src="lib/bootstrap4/js/bootstrap.min.js"></script>

    <script>

        // 11页
        $(function () {
            let API_URL = 'test_pagehelper.html';
            let curPage = getUrlParam('page');
            if (curPage === undefined) {
                curPage = 2;
            }
            console.log(curPage);
            let btnHtml = pageHelper(API_URL, parseInt(curPage), 108, 10, 3, '')
            $('div.page-helper').append(btnHtml);
        });

        /**
         * 生成分页按钮的html代码
         * @param curPage       当前页。理应由前端传给后端,但是前端的传参有可能超出实际范围,这就必须交由
         *                      后端来纠正之后,再查询对应页码的数据。然后后端将纠正后的当前页返回给前端,
         *                      以便前端来渲染页码按钮组。如果不传,由后端返回默认值1
         * @param total         总记录数。实际上,后端可以直接返回总页数就可以了,只不过有一定局限性:假如
         *                      前端还需要显示总记录数,凭借总页数和每页记录数,是无法计算出总记录数的。而返
         *                      回总记录数,前端可以自行计算总页数,同时还可以额外显示总记录数
         * @param count         每页显示的记录数,由前端传给后端。如果不传,使用后端定义的默认值
         * @param sideBtnCount  当前页按钮的左边有多少个按钮,不需要传给后端
         * @param urlParamsStr	点击页码切换页面时,携带的条件参数的字符串,拼接在url后面。由后端定义并传给
         *                      前端。后端接口并负责接收,按照自己定义的规则进行解析,拆解参数。
         *                      例子:&name=ysq&age=21。前面的&不能少
         */
        function pageHelper(API_URL, curPage, total, count, sideBtnCount, urlParamsStr) {
            // 计算总页数
            let pageCount = Math.ceil(total / count);

            let leftPage, rightPage;

            if (pageCount <= 2 * sideBtnCount + 1) {
                leftPage = 1;
                rightPage = pageCount;
            } else {
                // 计算按钮组最左端和最右端的页码
                // 将[1, pageCount]分为3个区间:
                // [1, sideBtnCount],[sideBtnCount+1, pageCount-sideBtnCount],[pageCount-sideBtnCount+1, pageCount]
                if (curPage > sideBtnCount && curPage <= pageCount - sideBtnCount) {
                    // [sideBtnCount+1, pageCount-sideBtnCount]
                    leftPage = curPage - sideBtnCount;
                    rightPage = curPage + sideBtnCount;

                } else if (curPage <= sideBtnCount) {
                    // [1, sideBtnCount]
                    leftPage = 1;
                    rightPage = 2 * sideBtnCount + 1;
                    // 越界时,修正当前页
                    if (curPage < 1) {
                        curPage = 1;
                    }

                } else if (curPage > pageCount - sideBtnCount) {
                    // [pageCount-sideBtnCount+1, pageCount]
                    leftPage = pageCount - 2 * sideBtnCount;
                    rightPage = pageCount;
                    // 越界时,修正当前页
                    if (curPage > pageCount) {
                        curPage = pageCount;
                    }
                }
            }

            return "<div class='pagination'>" +
                firstBtn('First') +
                preBtn('Pre') +
                numBtn(leftPage, rightPage) +
                nextBtn('Next') +
                lastBtn('Last') +
                "</div>";

            /**
             * 返回一个可点击的按钮的html代码
             * @param contentHtml   按钮中的内容
             */
            function clickableBtn(contentHtml, num) {
                return  `<li class='page-item'><a class='page-link' href='${API_URL}?page=${num}${urlParamsStr}'>${contentHtml}</a></li>`;
            }

            /**
             * 返回一个当前页按钮的html代码
             * @param contentHtml
             */
            function currentBtn(contentHtml) {
                return  `<li class='page-item active'><span class='page-link'>${contentHtml}</span></li>`;
            }

            /**
             * 返回上一页按钮的html代码
             * @param contentHtml
             */
            function preBtn(contentHtml) {
                if (curPage <= 1) {
                    return ''; // 我这里直接返回空,你也可以根据你的喜好,返回禁用点击的按钮
                }
                return clickableBtn(contentHtml, curPage - 1);
            }

            /**
             * 返回下一页按钮的html代码
             * @param contentHtml
             */
            function nextBtn(contentHtml) {
                if (curPage >= pageCount) {
                    return '';
                }
                return clickableBtn(contentHtml, curPage + 1);
            }

            /**
             * 返回首页按钮的html代码
             * @param contentHtml
             */
            function firstBtn(contentHtml) {
                if (leftPage <= 1) {
                    // 如果首页(1)已经显示在了按钮组(>=leftPage)当中,则不需要首页按钮,这里我直接返回空
                    return '';
                }
                return clickableBtn(contentHtml, 1);
            }

            /**
             * 返回末页按钮的html代码
             * @param contentHtml
             */
            function lastBtn(contentHtml) {
                if (pageCount <= rightPage) {
                    // 如果末页(pageCount)已经显示在了按钮组(<=rightPage)当中,则不需要首页按钮,这里我直接返回空
                    return '';
                }
                return clickableBtn(contentHtml, pageCount);
            }

            /**
             * 生成[left, right]区间的按钮的html代码
             * @param left
             * @param right
             */
            function numBtn(left, right) {
                let btnHtml = '';
                for (let i = left; i <= right; i++) {
                    if (i === curPage) {  // 当前页
                        btnHtml += currentBtn(i);
                    } else {
                        btnHtml += clickableBtn(i, i);
                    }
                }
                return btnHtml;
            }
        }

        // 获取指定的路径参数,获取不到返回空串
        function getUrlParam(key) {
            // ? 后面的
            let searchStr = window.location.search.substring(1);
            console.log(searchStr);

            let paramMap = new Array();

            let paramEntrys = searchStr.split('&');
            for(let i=0; i<paramEntrys.length; i++) {
                let entry = paramEntrys[i].split('=');
                paramMap[ entry[0] ] = entry[1];
            }

            console.log(paramMap);

            return paramMap[key];
        }
    </script>

</body>
</html>

 

Guess you like

Origin blog.csdn.net/qq_43290318/article/details/111601738