jq轻量级动态渲染表格

本来想用layui的,无奈插件开发担心第三方css注入影响到宿主网站,只能自己动手写了,模拟layui写的,可能存在bug,欢迎反馈
在这里插入图片描述

直接上代码,js已提供压缩,css自己压缩

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>数据转页面表格(动静态数据)</title>
<!--     <link rel="stylesheet" href="zsl.reset.css">
    <link rel="stylesheet" href="zsl.base.css"> -->
    <!-- <script type="text/javascript" src="zsl.base.js"></script> -->
    <script type="text/javascript" src="https://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
    <style type="text/css">
        .zslm-table table{
      
      
            width: 100%;
            border-collapse: collapse;
            border-spacing: 0;
        }
        .zslm-table thead{
      
      
            white-space: nowrap; 
        }
        .zslm-table tbody tr:hover, .zslm-table thead{
      
      
            background-color: #f2f2f2;
        }
        .zslm-table th, .zslm-table td{
      
      
            font-weight: 400;
            border: 1px solid rgb(230, 230, 230);
            border-image: initial;
            vertical-align: top;
            padding: 9px 15px;
            min-height: 20px;
            line-height: 20px;
            font-size: 14px;
            position: relative;
        }
        

        /*表头的排序样式*/
        .zslm-table .zsl-table_order{
      
      
            display: inline-block;
            position: relative;
            width: 10px;
            height: 4px;
            top: -3px;
            padding: 0 5px;
        }
        .zslm-table sup, .zslm-table sub{
      
      
            display: block;
            position: absolute;
            width: 0px;
            height: 0px;
            cursor: pointer;
            border-width: 5px;
            border-style: solid;
            border-color: transparent;
            border-image: initial;
        }
        .zslm-table sup, .zslm-table .zsl-table_order:hover sup:not(:hover){
      
      
            border-bottom-color: #ccc;
            bottom: 100%;
        }
        .zslm-table sup:hover, .zslm-table sup.zslz-active{
      
      
            border-bottom-color: #000;
        }
        .zslm-table sub, .zslm-table .zsl-table_order:hover sub:not(:hover){
      
      
            border-top-color: #ccc;
            top: 100%;
        }
        .zslm-table sub:hover, .zslm-table sub.zslz-active{
      
      
            border-top-color: #000;
        }

        /*处理表格图片类*/
        .zslm-table .zsl-table_img{
      
      
            display: inline-block;
            position: relative;
            width: 40px;
            height: 40px;
            padding-right: 10px;
            z-index: 1;
            margin: 0 auto;
            text-align: center;
        }
        .zslm-table .zsl-table_img img{
      
      
            display: inline-block;
            max-width: 100%;
            max-height: 100%;
            vertical-align: middle;
            position: relative;
        }
        .zslm-table .zsl-table_img_tip{
      
      
            display: none;
        }
        .zslm-table .zsl-table_img:hover .zsl-table_img_tip{
      
       
            position: absolute;
            display: block;
            top: 0;
            left: 100%;
            width: 300px;
            height: auto;
            padding: 10px;
            border-radius: 5px;
            box-shadow: 2px 2px 2px 1px #ccc;
            background-color: #3a3f51;
        }
        .zslm-table .zsl-table_img_tip:after {
      
      
            position: absolute;
            top: 15px;
            /* transform: translateY(-50%); */
            display: block;
            content: '';
            width: 0;
            height: 0;
            left: -19px;
            border-width: 10px;
            border-style: solid;
            border-color: transparent #3a3f51 transparent transparent;
        }

        /*底部页码选项*/
        .zslm-table .zsl-table_footer{
      
      
            width: 100%;
        }
        .zslm-table .zsl-table_page{
      
      
            padding: 10px 0;
            text-align: center;
            vertical-align: middle;
            white-space: nowrap;
        }
        .zslm-table .zsl-table_page>div{
      
      
            display: inline-block;
            height: 28px;
            line-height: 28px;
            padding: 0 15px;
            box-sizing: border-box;
        }
        .zslm-table .zsl-table_page span,.zslm-table .zsl-table_page a{
      
      
            display: inline-block;
            vertical-align: middle;
            height: 28px;
            line-height: 28px;
            background-color: rgb(255, 255, 255);
            color: rgb(51, 51, 51);
            font-size: 12px;
            margin-left: -1px;
            padding: 0px 15px;
            text-decoration: none;
            border: 1px solid #e2e2e2;
            box-sizing: border-box;
        }
        .zslm-table .zsl-table_page input{
      
      
            height: inherit;
            width: 40px;
            line-height: inherit;
            vertical-align: middle;
            background-color: rgb(255, 255, 255);
            box-sizing: border-box;
            text-align: center;
            border-radius: 2px;
            border: 1px solid #ccc;
            margin: 0px 5px;
            outline: 0px;
        }

        /*当前页码样式*/
        .zslm-table .zsl-table_page .zslz-active{
      
      
            background-color: rgb(0, 150, 136);
            border-color: rgb(0, 150, 136);
        }
        /*不可选样式*/
        .zslm-table .zsl-table_page .zslz-dis{
      
      
            color: rgb(210, 210, 210) !important;
            cursor: not-allowed !important;
        }
    </style>
</head>
<body>
    <div class="zsl-wrap zslj-mytable">
        
    </div>

<script type="text/javascript">
    class ZslTable{
      
      
        constructor(config, _jQuery){
      
      
            let that = this
                ,defaultOption = {
      
      
                    elem: ''
                    , cols: []
                    , data: []
                    , limit: 10
                    , page: 1
                    , total: null
                    , orderBy: {
      
      field: '', type: 'desc'}
                };
            // 设置jQuery
            that.jQuery = _jQuery?_jQuery: (window.jQuery? window.jQuery: null);
            if (that.jQuery == null) {
      
      
                throw '该组件需要jQuery的支持,请先引用jQuery再实例化';
                return false;
            }
            


            // 定义函数-start
            let checkType = (value) => {
      
      
                return Object.prototype.toString.call(value).slice(8, -1);
            }
            // 判断是否为空
            ,empty = (e) => {
      
      
                return null === e || (["Set", "Map"].includes(Object.prototype.toString.call(e).slice(8, -1)) ? 0 == e.size : "object" == typeof e ? Object.getOwnPropertyDescriptor(e, "length") ? !(e.length > 0) : !(Object.keys(e).length > 0) : 0 == e || !e);
            }
            // 注入样式
            ,injectStyle = () => {
      
      
                console.log('注入样式');
            }
            ,arraySort = function(e, t, n) {
      
      
                if (Array.isArray(e) && e[0].hasOwnProperty(t)) {
      
      
                    e = JSON.parse(JSON.stringify(e));
                    let r = function(e, t) {
      
      
                        return e < t ? 1 : e > t ? -1 : e == t ? 0 : void 0
                    };
                    "string" == typeof n && (n = "desc" === (n = n.toLowerCase()) || "asc" !== n && n),
                    n ? e.sort(function(e, n) {
      
      
                        return r(e[t], n[t])
                    }) : e.sort(function(e, n) {
      
      
                        return "" == e[t] || "" == n[t] ? r(e[t], n[t]) : -r(e[t], n[t])
                    })
                }
                return e
            }
            ;
            // 定义函数-end
            if (empty(config.elem)) {
      
      
                return false;
            }
            // 取dom容器
            that.thatDom = that.jQuery(config.elem);
            // 渲染模板
            that.template = {
      
      
                // 预加载
                loading: `<div class="zslj-loading zslm-loading"><div><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div></div>
                `
                , table: `<div class="zslm-table">
                    <div class="zsl-table_content">
                        <table>
                            <thead>
                                <% for(let items of data.cols) { %>
                                <tr>
                                    <% for(let val of items) { %>
                                    <th zsl-field="<%= val.field %>" <%= val.th_attr? handleAttr(val.th_attr, val): '' %>>
                                        <div>
                                            <span><%= val.title %></span>
                                            <% if (val.order) { %>
                                            <span class="zsl-table_order zslj-table_order">
                                                <%
                                                    if (val.order == 1) {
                                                        echo('<sup title="升序" class="' + ((data.orderBy.field == val.field && data.orderBy.type == 'asc')?'zslz-active':'')  + '" ></sup>');
                                                    } else if (val.order == 2) {
                                                        echo('<sub title="降序" class="' + ((data.orderBy.field == val.field && data.orderBy.type == 'desc')?'zslz-active':'') + '"></sub>');
                                                    } else {
                                                        echo('<sup title="升序" class="' + ((data.orderBy.field == val.field && data.orderBy.type == 'asc')?'zslz-active':'') + '"></sup><sub title="降序" class="' + ((data.orderBy.field == val.field && data.orderBy.type == 'desc')?'zslz-active':'') + '"></sub>')
                                                    }
                                                 %>
                                            </span>
                                            <% } %>
                                        </div>
                                    </th>
                                    <% } %>
                                </tr>
                                <% } %>
                            </thead>
                            <tbody>
                                <% for (let item of data.data) { %>
                                    <tr>
                                        <% for(let th of data.cols[0]) { %>
                                            <td <%= th.td_attr? handleAttr(th.td_attr, item): '' %>><div>
                                            <%
                                                if (!th.template) {
                                                    echo( item[th.field]);
                                                }
                                                else if (typeof th.template == 'function') {
                                                    echo (th.template(item));
                                                } else if (th.template == '__IMG__') {
                                                    let img = '<div class="zsl-table_img"><img src="' + item[th.field] + '"><div class="zsl-table_img_tip"><img src="' + item[th.field] + '"></div></div>';
                                                    echo(img);
                                                } else if (th.template == '__AIMG__') {
                                                    let aimg = '<div class="zsl-table_img"><a target="_blank" href="' + item[th.field] + '"><img src="' + item[th.field] + '"></a><div class="zsl-table_img_tip"><a target="_blank" href="' + item[th.field] + '"><img src="' + item[th.field] + '"></a></div></div>';
                                                    echo(aimg);
                                                } else {
                                                    echo(th.template);
                                                }
                                            %>
                                            </div></td>
                                        <% } %>
                                    </tr>
                                <% } %>
                            </tbody>
                        </table>
                    </div>
                    <% if (data.pageCount && data.pageCount > 1) { %>
                        <div class="zsl-table_footer">
                            <div class="zsl-table_page zslj-table_page">

                                <div>共 <%= data.pageCount %> 页</div>
                                
                                <% 
                                data.page = parseInt(data.page);
                                if (data.page < 2) {
                                    echo('<span class="zslz-dis">上一页</span>')
                                } else {
                                    echo('<a href="javascript:void(0)" zsl-page="' + (data.page - 1) + '">上一页</a>')
                                }

                                if (data.page == 1) {
                                    echo('<span class="zslz-active" zsl-page="1">1</span>')
                                } else {
                                    echo('<a href="javascript:void(0)" zsl-page="1">1</a>')
                                }
                                if (data.pageCount < 8) {
                                    for(let i = 2; i <= data.pageCount; i++) {
                                        if (i == data.page) {
                                            echo('<span class="zslz-active" zsl-page="' + i + '">' + i + '</span>')
                                        } else {
                                            echo('<a href="javascript:void(0)" zsl-page="' + i + '">' + i + '</a>');
                                        }
                                    }
                                } else {
                                    if (data.page > 4 && data.pageCount > 4) {
                                       echo('<span>···</span>')
                                    }
                                    for (let i= Math.max(2, Math.min(data.page-2, data.pageCount - 5)); i <= Math.min( Math.max(data.page + 2, 5), data.pageCount); i++) {
                                        if (i == data.page) {
                                            echo('<span class="zslz-active" zsl-page="' + i + '">' + i + '</span>')
                                        }else{
                                            echo('<a href="javascript:;" zsl-page="' + i + '">' + i + '</a>')
                                        }
                                    }
                                    if (data.page < data.pageCount - 3) {
                                        echo('<span>...</span>')
                                    }
                                    if(data.page < data.pageCount - 2){
                                        echo('<a href="javascript:;" zsl-page="' + data.pageCount + '">' + data.pageCount + '</a>');    
                                    }
                                }

                                if (data.pageCount <= data.page) {
                                    echo('<span class="zslz-dis">下一页</span>')
                                } else {
                                    echo('<a href="javascript:void(0)" zsl-page="' + (parseInt(data.page) + 1) + '">下一页</a>')
                                }

                                %>
                                
                                <div>
                                    到第<input type="text" name="zsl—page" zsl-min="1" zsl-max="<%= data.pageCount %>">页
                                    <a class="zlj-table_page_jump" href="javascript:void(0)">确定</a>
                                </div>
                            </div>
                        </div>
                        <% } %>
                    </div>
                `
            }
            // 转义去除空格
            that.template.table = that.template.table.replace(/\s+/g,' ').trim().replace(/[\r\n]/g, '').replace(/\>\s+\</g, '><');

            














            if (empty(config.limit)) {
      
      
                // 没有显示条数,默认显示所有
                defaultOption.limit = 99999;
            }
            that.tableConfig = {
      
      };
            for (let [key, item] of Object.entries(defaultOption)) {
      
      
                if (key == 'orderBy') {
      
      
                    if (empty(config[key]) || checkType(config[key]) != 'Object') {
      
      
                        config[key] = {
      
      
                            field: ''
                            ,type: 'desc'
                        }
                    } else {
      
      
                        config[key].type = config[key].type? config[key].type.toLowerCase() : '';
                        config[key].type = ['desc', 'asc'].includes(item.type)?item.type: (item.type? desc: asc);
                        config[key] = {
      
      
                            field: config[key].field?config[key].field: ''
                            , type: config[key].type
                        }
                    }
                }
                that.tableConfig[key] = config[key]? config[key]: item;
            }

            that.originalData = JSON.parse(JSON.stringify(that.tableConfig.data)); // 拷贝,防止参数引用导致的bug
            

            // 页码和条数
            that.tableConfig.limit = (isNaN(that.tableConfig.limit) || that.tableConfig.limit < 0) ? 10: parseInt(that.tableConfig.limit);// 显示条数
            that.tableConfig.page = (isNaN(that.tableConfig.page) || that.tableConfig.page < 1)? 1: parseInt(that.tableConfig.page);// 默认页码
            // 总页码
            that.tableConfig.pageCount = Math.ceil(that.tableConfig.data.length/config.limit);// 取总页码





            // 事件以及事件函数
            // 翻页-函数
            let turnPage = function(event) {
      
      
                that.tableConfig.page = parseInt(that.jQuery(this).attr('zsl-page'));
                if (that.onPage.bind(that)(event, that.tableConfig.page) === false) {
      
      
                    return true;
                }
                // 渲染页面
                that.render();
            }
            // 翻页事件-移除
            that.thatDom.unbind('click', turnPage);
            // 翻页事件-定义
            that.thatDom.on('click', '.zslj-table_page>a', turnPage);
            // 跳转页码-函数
            let jumpPage = function(event) {
      
      
                let iptPage =  that.thatDom.find('input[name="zsl—page"]').val();
                that.tableConfig.page = parseInt(iptPage);
                if (that.onPage.bind(that)(event, that.tableConfig.page) === false) {
      
      
                    return true;
                }
                that.render();
            }
            // 跳转页码-移除
            that.thatDom.unbind('click', jumpPage);
            // 跳转页码-定义
            that.thatDom.on('click', '.zlj-table_page_jump', jumpPage);

            // 手动输入页码
            let diyPage = function(event){
      
      
                let val = that.jQuery(this).val();
                if (isNaN(val)) {
      
      
                    that.jQuery(this).val('');
                    typeof layer == 'Object' && layer.msg('请输入阿拉伯数字');
                    return true;
                }
                val = parseInt(val);
                // 判断是否有最大或最小的限制
                let min = that.jQuery(this).attr('zsl-min');
                if (!isNaN(min) && val < parseInt(min)) {
      
      
                    that.jQuery(this).val(min);
                    typeof layer == 'Object' && layer.msg('输入值不能小于 ' + min);
                    return true;
                }
                let max = that.jQuery(this).attr('zsl-max');
                if (!isNaN(max) && val > parseInt(max)) {
      
      
                    that.jQuery(this).val(max);
                    typeof layer == 'Object' && layer.msg('输入值不能大于 ' + max);
                    return true;
                }
            }
            that.thatDom.unbind('blur', diyPage);
            that.thatDom.on('blur', 'input[name="zsl—page"]', diyPage);

            // 点击排序
            let changeOrder = function(event) {
      
      
                let tagName = event.target.tagName
                , orderType = tagName === 'SUP'?'asc': 'desc'
                , field = that.jQuery(this).parents('th').attr('zsl-field')
                ;
                that.thatDom.find('.zslj-table_order>*').removeClass('zslz-active');
                that.jQuery(this).addClass('zslz-active');


                // 处理排序
                if (that.onSort.bind(that)(event, field, orderType) === false) {
      
      
                	// 返回false 则 需要自己调用this.render(data, pageCount, page)渲染
                    return true;
                }

                // console.log(originalData);
                that.originalData = arraySort(that.originalData, field, orderType);
                // console.log(originalData);
                that.tableConfig.page = 1;
                that.tableConfig.orderBy.field = field;
                that.tableConfig.orderBy.type = orderType;

                that.render();
            }
            that.thatDom.unbind('click', changeOrder);
            that.thatDom.on('click', '.zslj-table_order sup,.zslj-table_order sub', changeOrder);

        }

        // 转换回html
        outputHtml(template, data){
      
      
            let that = this;
            let empty  = (e) => {
      
      
                    return null === e || (["Set", "Map"].includes(Object.prototype.toString.call(e).slice(8, -1)) ? 0 == e.size : "object" == typeof e ? Object.getOwnPropertyDescriptor(e, "length") ? !(e.length > 0) : !(Object.keys(e).length > 0) : 0 == e || !e);
                }
                , handleAttr = function(attrs, data){
      
      
                if (!attrs || Object.prototype.toString.call(attrs).slice(8, -1) !== 'Object') {
      
      
                    return '';
                }
                if (!data || Object.prototype.toString.call(data).slice(8, -1) !== 'Object') {
      
      
                    data = {
      
      };
                }
                let result = [];
                for(let [k, v] of Object.entries(attrs)) {
      
      
                    let out, reg = /\${(.*?)}/;
                    while (out = reg.exec(v)) {
      
      
                        v = v.replace(reg, data[out[1]]? data[out[1]]: 'undefined');
                    }
                    result.push(k + '="' + v + '"');
                }
                return result.join(' ');
            }
            ;
            // 合成模板内部函数
            let compileHtml = function(template){
      
      
                const evalExpr = /<%=(.+?)%>/g;
                const expr = /<%([\s\S]+?)%>/g;
                template = template
                    .replace(evalExpr, '`); \n echo( $1 ); \n echo(`')
                    .replace(expr, '`); \n $1 \n echo(`');
                template = 'echo(`' + template + '`);';
                let script = `(function parse(data){
                    let output = "";
                    function echo(html){
                        output += html;
                    }
                    ${ 
         template }
                    return output;
                })`;
                return script;
            }
            
            if(template){
      
      
                let parse = eval(compileHtml(template));
                return parse(data);
            }else{
      
      
                return '';
            }
        }


                // 渲染页面
        render(data, pageCount, page) {
      
      
            let that = this
                , config = JSON.parse(JSON.stringify(that.tableConfig))
                , html
                ;
            if (data && data.length) {
      
      
                config.data = data;
                (typeof pageCount != 'undefined' && !isNaN(pageCount) ) && (config.pageCount = pageCount); // 如果有返回总页码则重新赋值页码
                (typeof page != 'undefined' && !isNaN(page) ) && (config.page = page); // 如果筛选条件发生变化,页码重置为1 了,可以通过实例化的配置也可以传参到这里修改
            } else {
      
      
                let start, end;
                start = (config.page - 1) * config.limit, end = config.page * config.limit;

                config.data = that.originalData.slice( start, end);
            }
            html = that.outputHtml(that.template.table, config);
            that.thatDom.html(html);
        }

        // 提供外部使用的on函数
        // onPage
        onPage(event, page) {
      
      
            // console.log(event, page);
        }

        // onSort
        onSort(event, field, sortType) {
      
      
            // console.log(event, field, sortType);
        }
    }




        // 静态数据
    var tableConfig = {
      
      
        elem: '.zslj-mytable'
        ,cols: [
            [ // attr里如果是: ('123${xx}' => '123' + data.xx) ${}里的字符串会被替换成变量,如果不想被替换可以\\转义
                {
      
      field: 'id', title: 'ID', th_attr: {
      
      width: '100px', title: "ID啊啊啊"}, td_attr: {
      
      title: "ID是: ${id}"}, order: 3}
                ,{
      
      field: 'image', 'title': '图片', th_attr: {
      
      width: '50px', title: "产品图片"}, td_attr: {
      
      title: '点击查看原图'}, template: '__AIMG__'}
                ,{
      
      field: 'title', 'title': '产品名', th_attr: {
      
      width: '100px', title: "产品名"}, td_attr: {
      
      title: 'this is title:${title}'}}
                ,{
      
      field: 'textcontent', 'title': '描述内容', th_attr: {
      
      }, td_attr: {
      
      title: '${textcontent}'}}
                
            ]
        ]
        , data: [
             {
      
      id: '01', title: '标题01---01---01', image: 'https://static.newmorehot.com/Public/Index/images/logo-wish.png', textcontent: 'this is test 01010101010101010101'}
            ,{
      
      id: '02', title: '标题02---02---02', image: 'https://static.newmorehot.com/Public/Index/images/logo-aliExpress.png', textcontent: 'this is test 02020202020202020202'}
            ,{
      
      id: '03', title: '标题03---03---03', image: 'https://static.newmorehot.com/Public/Index/images/logo-amazon.png', textcontent: 'this is test 03030303030303030303'}
            ,{
      
      id: '04', title: '标题04---04---04', image: 'https://static.newmorehot.com/Public/Index/images/logo-joom.png', textcontent: 'this is test 04040404040404040404'}
            ,{
      
      id: '05', title: '标题05---05---05', image: 'https://static.newmorehot.com/Public/Index/images/logo-vova.png', textcontent: 'this is test 05050505050505050505'}
            ,{
      
      id: '06', title: '标题06---06---06', image: 'https://static.newmorehot.com/Public/Index/images/logo-mymall.png', textcontent: 'this is test 06060606060606060606'}
            ,{
      
      id: '07', title: '标题07---07---07', image: 'https://static.newmorehot.com/Public/Index/images/logo-shopee.png', textcontent: 'this is test 07070707070707070707'}
            ,{
      
      id: '08', title: '标题08---08---08', image: 'https://static.newmorehot.com/Public/Index/images/logo-lazada.png', textcontent: 'this is test 08080808080808080808'}
            ,{
      
      id: '09', title: '标题09---09---09', image: 'https://static.newmorehot.com/Public/Index/images/logo-walmart.png', textcontent: 'this is test 09090909090909090909'}
            ,{
      
      id: '10', title: '标题10---10---10', image: 'https://static.newmorehot.com/Public/Index/images/logo-wish.png', textcontent: 'this is test 10101010101010101010'}
            ,{
      
      id: '11', title: '标题11---11---11', image: 'https://static.newmorehot.com/Public/Index/images/logo-aliExpress.png', textcontent: 'this is test 11111111111111111111'}
            ,{
      
      id: '12', title: '标题12---12---12', image: 'https://static.newmorehot.com/Public/Index/images/logo-amazon.png', textcontent: 'this is test 12121212121212121212'}
            ,{
      
      id: '13', title: '标题13---13---13', image: 'https://static.newmorehot.com/Public/Index/images/logo-joom.png', textcontent: 'this is test 13131313131313131313'}
            ,{
      
      id: '14', title: '标题14---14---14', image: 'https://static.newmorehot.com/Public/Index/images/logo-vova.png', textcontent: 'this is test 14141414141414141414'}
            ,{
      
      id: '15', title: '标题15---15---15', image: 'https://static.newmorehot.com/Public/Index/images/logo-mymall.png', textcontent: 'this is test 15151515151515151515'}
            ,{
      
      id: '16', title: '标题16---16---16', image: 'https://static.newmorehot.com/Public/Index/images/logo-shopee.png', textcontent: 'this is test 16161616161616161616'}
            ,{
      
      id: '17', title: '标题17---17---17', image: 'https://static.newmorehot.com/Public/Index/images/logo-lazada.png', textcontent: 'this is test 17171717171717171717'}
            ,{
      
      id: '18', title: '标题18---18---18', image: 'https://static.newmorehot.com/Public/Index/images/logo-walmart.png', textcontent: 'this is test 18181818181818181818'}
            ,{
      
      id: '19', title: '标题19---19---19', image: 'https://static.newmorehot.com/Public/Index/images/logo-wish.png', textcontent: 'this is test 19191919191919191919'}
            ,{
      
      id: '20', title: '标题20---20---20', image: 'https://static.newmorehot.com/Public/Index/images/logo-aliExpress.png', textcontent: 'this is test 20202020202020202020'}
        ]
        , limit: 3
        , page: 1 // 当前页码
        , total: null // 总条数,如果ajax则有ajax提交,如果本地数据则 data.lengt
        , orderBy: {
      
      field: 'id', type: 'desc'}
    };

    var test = new ZslTable(tableConfig);

    // 页码重定义
    test.onPage = function(event, page){
      
      
        /**
         * this 为实例化出来的 test
         * event 鼠标点击事件
         * page 传过来的页码,当前事件后的页码数
         */
         // 如ajax请求后得到了数据result = {code: 0, msg: 'success', data: {data: [{...}, ...], total: '总条数'}}
         // this.render(result.data.data, pageCount)


        return true;// 返回false,不走类定义里的渲染了,需要自己render();
    }
    // 排序事件重定义
    test.onSort = function(event, field, orderType) {
      
      
        // 重新定义数据需要false,如果不改变初始化的数据,只是点击排序后执行一些行为,不可返回false,也不能调用this.render();

        // this.render(result.data.data, pageCount);
        return true;
    }
    test.render();
</script>
</body>
</html>

压缩的js

class ZslTable{
    
    constructor(e,t){
    
    e=JSON.parse(JSON.stringify(e));let a=this,i={
    
    elem:"",cols:[],data:[],limit:10,page:1,total:null,orderBy:{
    
    field:"",type:""}};if(a.jQuery=t||(window.jQuery?window.jQuery:null),null==a.jQuery)throw"该组件需要jQuery的支持,请先引用jQuery再实例化";let l=e=>Object.prototype.toString.call(e).slice(8,-1),s=e=>!(null!==e&&(["Set","Map"].includes(Object.prototype.toString.call(e).slice(8,-1))?0!=e.size:"object"==typeof e?Object.getOwnPropertyDescriptor(e,"length")?e.length>0:Object.keys(e).length>0:0!=e&&e));if(s(e.elem))return!1;a.thatDom=a.jQuery(e.elem),a.template={
    
    loading:'<div class="zslj-loading zslm-loading"><div><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div></div>',table:"<div class=\"zslm-table\"><div class=\"zsl-table_content\"><table><thead><% for(let items of data.cols) { %><tr><% for(let val of items) { %><th zsl-field=\"<%= val.field %>\" <%= val.th_attr? handleAttr(val.th_attr, val): '' %>><div><span><%= val.title %></span><% if (val.order) { %><span class=\"zsl-table_order zslj-table_order\"><% if (val.order == 1) { echo('<sup title=\"升序\" class=\"' + ((data.orderBy.field == val.field && data.orderBy.type == 'asc')?'zslz-active':'') + '\" ></sup>'); } else if (val.order == 2) { echo('<sub title=\"降序\" class=\"' + ((data.orderBy.field == val.field && data.orderBy.type == 'desc')?'zslz-active':'') + '\"></sub>'); } else { echo('<sup title=\"升序\" class=\"' + ((data.orderBy.field == val.field && data.orderBy.type == 'asc')?'zslz-active':'') + '\"></sup><sub title=\"降序\" class=\"' + ((data.orderBy.field == val.field && data.orderBy.type == 'desc')?'zslz-active':'') + '\"></sub>') } %></span><% } %></div></th><% } %></tr><% } %></thead><tbody><% for (let item of data.data) { %><tr><% for(let th of data.cols[0]) { %><td <%= th.td_attr? handleAttr(th.td_attr, item): '' %>><div><% if (!th.template) { echo( item[th.field]); } else if (typeof th.template == 'function') { echo (th.template(item)); } else if (th.template == '__IMG__') { let img = '<div class=\"zsl-table_img\"><img src=\"' + item[th.field] + '\"><div class=\"zsl-table_img_tip\"><img src=\"' + item[th.field] + '\"></div></div>'; echo(img); } else if (th.template == '__AIMG__') { let aimg = '<div class=\"zsl-table_img\"><a target=\"_blank\" href=\"' + item[th.field] + '\"><img src=\"' + item[th.field] + '\"></a><div class=\"zsl-table_img_tip\"><a target=\"_blank\" href=\"' + item[th.field] + '\"><img src=\"' + item[th.field] + '\"></a></div></div>'; echo(aimg); } else { echo(th.template); } %></div></td><% } %></tr><% } %></tbody></table></div><% if (data.pageCount && data.pageCount > 1) { %><div class=\"zsl-table_footer\"><div class=\"zsl-table_page zslj-table_page\"><div>共 <%= data.pageCount %> 页</div><% data.page = parseInt(data.page); if (data.page < 2) { echo('<span class=\"zslz-dis\">上一页</span>') } else { echo('<a href=\"javascript:void(0)\" zsl-page=\"' + (data.page - 1) + '\">上一页</a>') } if (data.page == 1) { echo('<span class=\"zslz-active\" zsl-page=\"1\">1</span>') } else { echo('<a href=\"javascript:void(0)\" zsl-page=\"1\">1</a>') } if (data.pageCount < 8) { for(let i = 2; i <= data.pageCount; i++) { if (i == data.page) { echo('<span class=\"zslz-active\" zsl-page=\"' + i + '\">' + i + '</span>') } else { echo('<a href=\"javascript:void(0)\" zsl-page=\"' + i + '\">' + i + '</a>'); } } } else { if (data.page > 4 && data.pageCount > 4) { echo('<span>···</span>') } for (let i= Math.max(2, Math.min(data.page-2, data.pageCount - 5)); i <= Math.min( Math.max(data.page + 2, 5), data.pageCount); i++) { if (i == data.page) { echo('<span class=\"zslz-active\" zsl-page=\"' + i + '\">' + i + '</span>') }else{ echo('<a href=\"javascript:;\" zsl-page=\"' + i + '\">' + i + '</a>') } } if (data.page < data.pageCount - 3) { echo('<span>...</span>') } if(data.page < data.pageCount - 2){ echo('<a href=\"javascript:;\" zsl-page=\"' + data.pageCount + '\">' + data.pageCount + '</a>'); } } if (data.pageCount <= data.page) { echo('<span class=\"zslz-dis\">下一页</span>') } else { echo('<a href=\"javascript:void(0)\" zsl-page=\"' + (parseInt(data.page) + 1) + '\">下一页</a>') } %><div> 到第<input type=\"text\" name=\"zsl—page\" zsl-min=\"1\" zsl-max=\"<%= data.pageCount %>\">页 <a class=\"zlj-table_page_jump\" href=\"javascript:void(0)\">确定</a></div></div></div><% } %></div>"},s(e.limit)&&(i.limit=99999),a.tableConfig={
    
    };for(let[t,r]of Object.entries(i))"orderBy"==t&&(s(e[t])||"Object"!=l(e[t])?e[t]={
    
    field:"",type:""}:(e[t].type=e[t].type?e[t].type.toLowerCase():"",e[t].type=["desc","asc"].includes(e[t].type)?e[t].type:e[t].type?"desc":"asc",e[t]={
    
    field:e[t].field?e[t].field:"",type:e[t].type})),a.tableConfig[t]=e[t]?e[t]:r;a.originalData=JSON.parse(JSON.stringify(a.tableConfig.data)),a.tableConfig.limit=isNaN(a.tableConfig.limit)||a.tableConfig.limit<0?10:parseInt(a.tableConfig.limit),a.tableConfig.page=isNaN(a.tableConfig.page)||a.tableConfig.page<1?1:parseInt(a.tableConfig.page),a.tableConfig.pageCount=Math.ceil(a.tableConfig.data.length/e.limit);let r=function(e){
    
    if(a.tableConfig.page=parseInt(a.jQuery(this).attr("zsl-page")),!1===a.onPage.bind(a)(e,a.tableConfig.page))return!0;a.render()};a.thatDom.unbind("click",r),a.thatDom.on("click",".zslj-table_page>a",r);let o=function(e){
    
    let t=a.thatDom.find('input[name="zsl—page"]').val();if(a.tableConfig.page=parseInt(t),!1===a.onPage.bind(a)(e,a.tableConfig.page))return!0;a.render()};a.thatDom.unbind("click",o),a.thatDom.on("click",".zlj-table_page_jump",o);let n=function(e){
    
    let t=a.jQuery(this).val();if(isNaN(t))return a.jQuery(this).val(""),"Object"==typeof layer&&layer.msg("请输入阿拉伯数字"),!0;t=parseInt(t);let i=a.jQuery(this).attr("zsl-min");if(!isNaN(i)&&t<parseInt(i))return a.jQuery(this).val(i),"Object"==typeof layer&&layer.msg("输入值不能小于 "+i),!0;let l=a.jQuery(this).attr("zsl-max");return!isNaN(l)&&t>parseInt(l)?(a.jQuery(this).val(l),"Object"==typeof layer&&layer.msg("输入值不能大于 "+l),!0):void 0};a.thatDom.unbind("blur",n),a.thatDom.on("blur",'input[name="zsl—page"]',n);let p=function(e){
    
    let t="SUP"===e.target.tagName?"asc":"desc",i=a.jQuery(this).parents("th").attr("zsl-field");if(a.thatDom.find(".zslj-table_order>*").removeClass("zslz-active"),a.jQuery(this).addClass("zslz-active"),!1===a.onSort.bind(a)(e,i,t))return!0;a.originalData=function(e,t,a){
    
    if(Array.isArray(e)&&e[0].hasOwnProperty(t)){
    
    e=JSON.parse(JSON.stringify(e));let i=function(e,t){
    
    return e<t?1:e>t?-1:e==t?0:void 0};"string"==typeof a&&(a="desc"===(a=a.toLowerCase())||"asc"!==a&&a),a?e.sort(function(e,a){
    
    return i(e[t],a[t])}):e.sort(function(e,a){
    
    return""==e[t]||""==a[t]?i(e[t],a[t]):-i(e[t],a[t])})}return e}(a.originalData,i,t),a.tableConfig.page=1,a.tableConfig.orderBy.field=i,a.tableConfig.orderBy.type=t,a.render()};a.thatDom.unbind("click",p),a.thatDom.on("click",".zslj-table_order sup,.zslj-table_order sub",p)}outputHtml(template,data){
    
    let that=this,empty=e=>!(null!==e&&(["Set","Map"].includes(Object.prototype.toString.call(e).slice(8,-1))?0!=e.size:"object"==typeof e?Object.getOwnPropertyDescriptor(e,"length")?e.length>0:Object.keys(e).length>0:0!=e&&e)),handleAttr=function(e,t){
    
    if(!e||"Object"!==Object.prototype.toString.call(e).slice(8,-1))return"";t&&"Object"===Object.prototype.toString.call(t).slice(8,-1)||(t={
    
    });let a=[];for(let[i,l]of Object.entries(e)){
    
    let e,s=/\${(.*?)}/;for(;e=s.exec(l);)l=l.replace(s,t[e[1]]?t[e[1]]:"undefined");a.push(i+'="'+l+'"')}return a.join(" ")},compileHtml=function(e){
    
    return`(function parse(data){\n                    let output = "";\n                    function echo(html){\n                        output += html;\n                    }\n                    ${
      
      e="echo(`"+(e=e.replace(/<%=(.+?)%>/g,"`); \n echo( $1 ); \n echo(`").replace(/<%([\s\S]+?)%>/g,"`); \n $1 \n echo(`"))+"`);"}\n                    return output;\n                })`};if(template){
    
    let parse=eval(compileHtml(template));return parse(data)}return""}render(e,t,a){
    
    let i,l=this,s=JSON.parse(JSON.stringify(l.tableConfig));if(e&&e.length)s.data=e,void 0!==t&&!isNaN(t)&&(s.pageCount=t),void 0!==a&&!isNaN(a)&&(s.page=a);else{
    
    let e,t;e=(s.page-1)*s.limit,t=s.page*s.limit,s.data=l.originalData.slice(e,t)}i=l.outputHtml(l.template.table,s),l.thatDom.html(i)}onPage(e,t){
    
    }onSort(e,t,a){
    
    }}

猜你喜欢

转载自blog.csdn.net/qq_35606400/article/details/120573076