jQuery生成多层复杂表头方法

目录
文章目录隐藏
  1. 实现思路
  2. 数据
  3. 方法一
  4. 方法二

最近在做公司系统时用到了表格,而表格的表头是根据一个数组生成,如果只是普通的单层表头很容易实现,但是如果是复杂的表头,就要挺麻烦的,主要是我的数组结构是树形数组,实现需要递归,递归过程需要考虑到<th> 的 colspanrowspan 的设置。

实现思路

设每一项为 item:

  • colspan的值 :item没有childrencolspan=1;如果有childrencolspan的值则为它的所有childrencolspan的总和();
  • rowapsn的值:itemchildren,它的rowspan=1item没有childrenrowspan 的值为最深层级+ 1-当前层级(maxrank+1 - rank)

数据

var columns = [
    {
        codeName: '系统分析师',
        key: 'GradeOrLevel',
        children: [
            {
                codeName: '初级',
                codeVlaue: 'BA-P1'
            },
            {
                codeName: '中级',
                codeVlaue: 'BA-P2'
            },
            {
                codeName: '高级',
                codeVlaue: 'BA-P3'
            }
        ]
    },{
        codeName: 'UI',
        key: 'GradeOrLevel',
        children: [
            {
                codeName: '初级',
                codeVlaue: 'UI-P1'
            },
            {
                codeName: '中级',
                codeVlaue: 'UI-P2'
            },
            {
                codeName: '高级',
                codeVlaue: 'UI-P3'
            }
        ]
    },
    {
        codeName: '开发工程师',
        key: 'GradeOrLevel',
        children: [
            {
                codeName: '初级',
                codeVlaue: 'AD-P1'
            },
            {
                codeName: '中级',
                codeVlaue: 'AD-P2'
            },
            {
                codeName: '高级级',
                codeVlaue: 'AD-P3'
            }
        ]
    },
];

方法一

var trs = [];
start = new Date().getTime();
foo(columns);

function pushTrs(arr) {
    var rank = arr[0].rank;
    if (trs[rank]) {
        $.merge(trs[rank], arr)
    } else {
        trs[rank] = arr;
    }
}

function render() {
    var $thead = $('<thead></thead>');
    var len = trs.length;
    for (var i = 0; i < trs.length; i++) {
        var $tr = $('<tr></tr>');
        for (var j = 0; j < trs[i].length; j++) {
            var $th = $('<th>' + trs[i][j].codeName + '</th>');
            $th.attr('colspan', trs[i][j].colspan);
            if (trs[i][j].rowspan) {
                $th.attr('rowspan', trs[i][j].rowspan);
            } else {
                $th.attr('rowspan', len - trs[i][j].rank);
            }
            $tr.append($th);
        }
        $thead.append($tr);
    }
    $('#myTable table').append($thead);
    end = new Date().getTime();
    console.log(end - start);
}

function foo(arr, parent) {
    for (var i = 0; i < arr.length; i++) {
        len = arr[i].children ? arr[i].children.length : 0;
        arr[i].rank = parent ? parent.rank + 1 : 0;
        if (len > 0) {//children 存在
            arr[i].rowspan = 1;
            foo(arr[i].children, arr[i]);
        } else {//children 不存在
            arr[i].colspan = 1;
        }
        if (parent) {//parent 的 colspan 为 children 的 colspan 总和
            parent.colspan = parent.colspan ? parent.colspan : 0;
            parent.colspan += arr[i].colspan;
        }
    }

    pushTrs(arr);

    if (arr[0].rank == 0) {//最后一次递归结束
        render();
    }
}

方法二

var $thead = $('<thead></thead>');
foo(columns);

function foo(arr, parent) {
    var $tr = $('<tr></tr>');
    for (var i = 0; i < arr.length; i++) {
        var $th = $('<th>' + arr[i].codeName + '</th>');
        len = arr[i].children ? arr[i].children.length: 0;
        arr[i].rank = parent ? parent.rank + 1 : 0;
        $tr.data('rank', arr[i].rank);
        if (len > 0) { //children 存在
            $th.attr('rowspan', 1);
            foo(arr[i].children, arr[i]);
        } else { //children 不存在
            arr[i].colspan = 1;
        }
        if (parent) { //parent 的 colspan 为 children 的 colspan 总和
            parent.colspan = parent.colspan ? parent.colspan: 0;
            parent.colspan += arr[i].colspan;
        }
        $th.attr('colspan', arr[i].colspan);
        $tr.append($th);
    }
    var rank = $tr.data('rank');
    if ($thead.find('tr').length > 0) {
        var flag = true;
        $thead.find('tr').each(function() { //插入 tr 并且排好顺序
            if ($(this).data('rank') > rank) {
                $(this).before($tr);
                flag = false;
                return false;
            } else if ($(this).data('rank') == rank) {
                $(this).append($tr.find('th')) flag = false;
                return false;
            }
        }) if (flag) {
            $thead.append($tr)
        }
    } else {
        $thead.append($tr)
    }

    if (rank == 0) { //最后一次递归结束
        var maxRank = $thead.children('tr:last').data('rank'); //求最大 rank
        $thead.find('th').each(function() { //设置 rowspan 
            if (!$(this).attr('rowspan')) {
                var rowspan = maxRank - $(this).parent('tr').data('rank') + 1;
                console.log(maxRank) $(this).attr('rowspan', rowspan);
            }
        }) $('#myTable table').append($thead);
    }
}

最终实现效果:

jQuery 生成多层复杂表头方法

注意:从执行效率上来看,方式一比方式二的高。

「点点赞赏,手留余香」

1

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
码云笔记 » jQuery生成多层复杂表头方法

发表回复