jquery实现表格复杂表头

先上图:
这里写图片描述

目前在做一个表格插件,表格的表头是根据一个数组生成,如果只是普通的单层表头很容易实现,但是如果是复杂的表头,就要挺麻烦的,主要是我的数组结构是树形数组,实现需要递归,递归过程要考虑到<th>colspanrowspan 的设置,我自己对递归也不是很懂,只能慢慢摸索。

其实自己手写一个复杂的表头也不难,自己就先写一个简单的找规律:

<table class="table table-bordered">
        <thead>
            <tr>
                <th colspan="1" rowspan="4">姓名</th>
                <th colspan="1" rowspan="4">年龄</th>
                <th colspan="6" rowspan="1">爱好</th>
            </tr>
        <tr>
            <th colspan="2" rowspan="1">看书</th>
            <th colspan="4" rowspan="1">打球</th>
        </tr>
            <tr>
                <th colspan="1" rowspan="2">名著</th>
                <th colspan="1" rowspan="2">小说</th>
                <th colspan="1" rowspan="2">篮球</th>
                <th colspan="1" rowspan="2">排球</th>
                <th colspan="2" rowspan="1">足球</th>
            </tr>
        <tr>
            <th colspan="1" rowspan="1">足球1</th>
            <th colspan="1" rowspan="1">足球1</th>
        </tr>
        </thead>
    </table>
var columns = [
  {
    title: '姓名',
    key: 'name'
  },
  {
    title: '年龄',
    key: 'age'
  },
  {
    title: '爱好',
    key: 'like',
    children: [
      {
        title: '看书',
        key: 'like1',
        children: [
          {
            title: '名著',
            key: 'book1'
          },
          {
            title: '小说',
            key: 'book2'
          }
        ]
      },
      {
        title: '打球',
        key: 'like2',
        children: [
          {
            title: '篮球',
            key: 'ball1'
          },
          {
            title: '排球',
            key: 'ball2'
          }, {
            title: '足球',
            key: 'ball3',
            children: [
              {
                title: '足球1',
                key: 'ball31'
              },
              {
                title: '足球2',
                key: 'ball32'
              }
            ]
          }
        ]
      }
    ]
  }
];

思路:
设每一项为 item
- 求colspan的值 :item没有children则colspan=1;如果有children,colspan的值则为它的所有children的colspan的总和();
- 求rowapsn的值:item有children,它的rowspan=1;item没有children,rowspan 的值为最深层级+ 1-当前层级 (maxrank+1 - rank

上代码:
方法1:

var trs = [];
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].title +'</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);

}

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].title + '</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);
  }

}

注:方式一的执行效率比方式二的高
演示地址:查看

猜你喜欢

转载自blog.csdn.net/liangrongliu1991/article/details/80321089
今日推荐