先上图:
目前在做一个表格插件,表格的表头是根据一个数组生成,如果只是普通的单层表头很容易实现,但是如果是复杂的表头,就要挺麻烦的,主要是我的数组结构是树形数组,实现需要递归,递归过程要考虑到<th>
的 colspan
和rowspan
的设置,我自己对递归也不是很懂,只能慢慢摸索。
其实自己手写一个复杂的表头也不难,自己就先写一个简单的找规律:
<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);
}
}
注:方式一的执行效率比方式二的高
演示地址:查看