前言

近几年根本都是开发SPA利用,敌人找我帮忙做一个简略的后盾治理的模块,是传统的ASP.NET WEB页面,不过我这次还是写独立的前端界面的,只是会基于他们零碎应用的框架去开发(jq+bootstrap)。

工作

  • 列表页(搜寻、表格展现、分页)
  • 表单提交页(新增/编辑)

技术框架

  • jQuery
  • bootstrap.js(v3)
  • art-template
  • wdate
  • ...

例子:https://blog.csdn.net/weixin_...

开发笔记

原我的项目用的是v3版本的bootstrap

表格

原我的项目中表格有用bootstrapTable插件(性能看着挺齐全),因为其官网例子很多加载不进去(控制台报错),本人对它不相熟,且工作工夫紧放心用了前面要扩大不不便,我就没用它的。

表格我是申请数据后,间接用art-template模版引擎去渲染,简略的示例界面如下:

界面:

<!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.0">    <title>art-Templat例子</title>    <script src="./lib/art-template/template-web.js"></script>    <style>        table {            border-collapse: collapse;            border-spacing: 0;        }        table .th {            background-color: #f5f5f5;            font-size: 12px;            font-weight: bold;        }        table tr {            border-top: 1px solid #dfdfdf;        }        table tr:last-child {            border-bottom: 1px solid #dfdfdf;        }        table tr td {            padding: 4px 6px;            font-size: 12px;        }    </style></head><body>    <!--列表-->    <table class="table">        <tbody id="table-tbody">        </tbody>    </table>    <!--列表内容模版-->    <script id="tpl-table-tbody" type="text/html">        <tr class="th">            <td>ID</td>            <td>订单号</td>            <td>收货人</td>            <td>手机号</td>            <td>状态</td>            <td>创建人</td>            <td>创立工夫</td>        </tr>        {{each list}}        <tr>            <td>{{$value.id}}</td>            <td>{{$value.orderNo}}</td>            <td>{{$value.receiver}}</td>            <td>{{$value.phone}}</td>            <td>{{$value.status}}</td>            <td>{{$value.creator}}</td>            <td>{{$value.createTime}}</td>        </tr>        {{/each}}    </script></body></html>

对应JS:

        var html = template('tpl-table-tbody', {            list: [{                id: 'XK001',                orderNo: 'ORD202205180001',                receiver: '张三',                phone: '13512341234',                status: '待发货',                creator: '管理员',                createTime: '2022-03-20 15:30:22'            }, {                id: 'XK002',                orderNo: 'ORD202205180002',                receiver: '张三',                phone: '13512341234',                status: '已实现',                creator: '管理员',                createTime: '2022-03-02 18:30:22'            }, {                id: 'XK003',                orderNo: 'ORD202205180003',                receiver: '张三',                phone: '13512341234',                status: '待收货',                creator: '管理员',                createTime: '2022-03-16 20:30:22'            }]        });        document.getElementById('table-tbody').innerHTML = html;

分页

因为表格是独自渲染了,就得再独自思考分页。
想要的成果:

我试了一下boostrapPagination,成果和想要的差异有点大,如下图所示,页数很多时没有思考...的展现,且首尾页时默认暗藏头尾按钮。

最初,本人基于网上的一个简略的例子重写了一个分页的小插件,成果如下。

demo页面:

<!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.0">    <title>KPagination</title>    <!-- 引入 zepto CDN 链接 -->    <script src="https://cdnjs.gtimg.com/cdnjs/libs/zepto/1.1.4/zepto.js"></script>    <style>        body {            font-size: 14px;        }        button {            border-style: none;            line-height: 30px;            padding: 0 12px;            margin-bottom: 20px;        }    </style></head><body>    <button onclick="search()">搜寻</button>    <div id="content"></div>    <div id="pagination"></div></body><script src="./js/kPagination.js"></script></html>

页面JS:

    function search() {        getKPagination({            total: 185,            totalPage: 18,            curPage: 1,            initCallback: function (page) {                $('#content').html(`以后页码:${page}`);            },            toPageCallback: function (page) {                $('#content').html(`以后页码:${page}`);            }        });    }

KPagination.js

function getKPagination(opt) {    const defaultOpt = {        totalPage: 0,        curPage: 1,        total: 0,        pageSize: 10,        bootstrapCss: false //默认没引bootstarp款式。(此时会加上.pagination相干的款式)    }    const option = Object.assign({}, defaultOpt, opt);    const kPagination = {        curPage: option.curPage,        totalPage: option.totalPage,        total: option.total,        pageSize: option.pageSize,        toPageCallback: option.toPageCallback,        initCallback: option.initCallback,        pageEleID: 'pagination',        init: false,        getPaginationHtml: function (totalPage, curPage, total) {            var paginationInfo = "<ul class=\"pagination pagination-sm\" >" +                "<li><span class=\"label\">共" + total + "条记录</span></li>" +                "<li><a data-i=" + (curPage - 1) +                " data-disabled=\"" + ((curPage - 1) == 0 ? "true" : "false") + "\">«上一页</a></li>";            if (totalPage <= 10) {                for (var i = 1; i <= totalPage; i++) {                    paginationInfo += "<li><a data-i=" + i +                        ">" + i + "</a></li>";                }            } else {                if (curPage <= 3) {                    for (var i = 1; i <= curPage + 2; i++) {                        paginationInfo += "<li><a  data-i=" + i +                            ">" + i + "</a></li>";                    }                    paginationInfo += "<li><span class=\"label\">...</span></li>";                    paginationInfo += "<li><a  data-i=" + totalPage +                        ">" + totalPage + "</a></li>";                } else if (curPage <= totalPage - 5) {                    paginationInfo += "<li><a  data-i=" + 1 +                        ">" + 1 + "</a></li>";                    paginationInfo += "<li><span class=\"label\">...</span></li>";                    for (var i = curPage - 1; i <= curPage + 2; i++) {                        paginationInfo += "<li><a data-i=" + i +                            ">" + i + "</a></li>";                    }                    paginationInfo += "<li><span class=\"label\">...</span></li>";                    paginationInfo += "<li><a data-i=" + totalPage +                        ">" + totalPage + "</a></li>";                } else {                    paginationInfo += "<li><a data-i=" + 1 +                        ">" + 1 + "</a></li>";                    paginationInfo += "<li><span class=\"label\">...</span></li>";                    for (var i = curPage - 1; i <= totalPage; i++) {                        paginationInfo += "<li><a data-i=" + i +                            ">" + i + "</a></li>";                    }                }            }            paginationInfo += "<li><a data-i=" + (curPage + 1) +                " data-disabled=\"" + (totalPage == 0 || curPage == totalPage ? "true" : "false") + "\">下一页»</a></li>";            return paginationInfo;        },        refreshPagination: function (totalPage, curPage, total) {            if (total > 0 && (curPage < 1 || curPage > totalPage)) {                return;            }            var paginationInfo = this.getPaginationHtml(totalPage, curPage, total);            document.getElementById(this.pageEleID).innerHTML = paginationInfo;            $('.pagination li a').removeClass('current');            $('.pagination li a[data-i="' + curPage + '"]').addClass('current');        },        //分页条初始化        init: function () {            this.addStyle();            var paginationInfo = this.getPaginationHtml(this.totalPage, this.curPage, this.total);            document.getElementById(this.pageEleID).innerHTML = paginationInfo;            $('.pagination li a[data-i="' + this.curPage + '"]').addClass('current');            //分页条点击切换查问            $('#' + this.pageEleID).on('click', '.pagination li a', (e) => {                if (e.target.dataset['i'] == undefined) return false;                if (e.target.dataset['disabled'] == 'true') return false;                const page = parseInt(e.target.dataset['i']);                this.toPageCallback && this.toPageCallback(page);                this.refreshPagination(this.totalPage, page, this.total);                return false;            });            this.initCallback && this.initCallback(this.curPage);        },        addStyle: function () {            let style = '';            if (!this.bootstrapCss) {                style += `                .pagination {                    display: inline-block;                    padding-left: 0;                    margin: 20px 0;                    border-radius: 4px                }                                .pagination>li {                    display: inline                }                                .pagination>li>a,.pagination>li>span {                    position: relative;                    float: left;                    padding: 6px 12px;                    margin-left: -1px;                    line-height: 1.428571429;                    text-decoration: none;                    background-color: #fff;                    border: 1px solid #ddd                }                                .pagination>li:first-child>a,.pagination>li:first-child>span {                    margin-left: 0;                    border-bottom-left-radius: 4px;                    border-top-left-radius: 4px                }                                .pagination>li:last-child>a,.pagination>li:last-child>span {                    border-top-right-radius: 4px;                    border-bottom-right-radius: 4px                }                                .pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus {                    background-color: #eee                }                                .pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus {                    z-index: 2;                    color: #fff;                    cursor: default;                    background-color: #488FCD;                    border-color: #488FCD                }                                .pagination>.disabled>span,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus {                    color: #999;                    cursor: not-allowed;                    background-color: #fff;                    border-color: #ddd                }                                .pagination-lg>li>a,.pagination-lg>li>span {                    padding: 10px 16px;                    font-size: 18px                }                                .pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span {                    border-bottom-left-radius: 6px;                    border-top-left-radius: 6px                }                                .pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span {                    border-top-right-radius: 6px;                    border-bottom-right-radius: 6px                }                                .pagination-sm>li>a,.pagination-sm>li>span {                    padding: 5px 10px;                    font-size: 12px                }                                .pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span {                    border-bottom-left-radius: 3px;                    border-top-left-radius: 3px                }                                .pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span {                    border-top-right-radius: 3px;                    border-bottom-right-radius: 3px                }                `;            }            style += `            .pagination>li a:not([data-disabled="true"]):active{                color: #fff;                background: #488FCD;                border-color: #488FCD;            }            .pagination>li a:not([data-disabled="true"]).current {                color: #fff;                background: #488FCD;                border-color: #488FCD;            }            .pagination a[data-disabled="true"] {                color: #afafaf;                cursor: not-allowed;            }            .pagination a[data-disabled="true"]:hover {                color: #afafaf;                cursor: not-allowed;            }                        .pagination>li>a{                cursor:pointer;            }            .pagination>li>a, .pagination>li>span {                color: #333;            }            .pagination>li .label,.pagination .label:hover{                cursor:initial;                background-color: #ffffff;            }            `;            const styleEle = document.createElement('style');            styleEle.type = 'text/css';            styleEle.innerText = style;            var head = document.getElementsByTagName('head')[0]            head.appendChild(styleEle);        }    }    kPagination.init();    return kPagination;}

最初

良久没有这样比拟“原生态”的写前端了,哈哈哈,写写小工具小插件,还是感觉挺好玩的,这篇文章只是记录了:

  • 页面渲染应用的是art-template模版引擎
  • 简略封装了一个分页小插件的KPagination.js
本次开发工作的笔记待续哦,前面还会补充其余性能的一些总结。
欢送大家戳戳留下足迹,欢送留言交换哦~

参考文献

  • Bootstrap前端分页的实现(带省略号)