单元格自动合并
>>> Github 在线示例
构造数据(第一次)
<table id="table">
<thead>
<tr>
<th>公司地点</th>
<th>部门名称</th>
<th>小组名称</th>
<th>项目名称</th>
<th>参与人员</th>
<th>备注信息</th>
</tr>
</thead>
<tbody>
<!-- tr td 就不贴代码了,占地方,只贴一下构造后的效果图吧 -->
</tbody>
</table>
构造后效果图(第一次)
JQuery 合并代码(第一次)
$(function () {
MergeCol_v1('#table', 5);
})
/*表格合并列单元格,colIdx要合并的前多少列
* @param tableid 表ID,例如#Table_Center
* @param colIdx 列位置,前 colIdx 列
*/
function MergeCol_v1(tableid, colIdx) {
var that;
$(tableid + ' tr').each(function (row) {
/*取该行下的指定列单元格*/
$(this).find('td:eq(' + colIdx + ')').filter(':visible').each(function (col) {
/*临时存储当前单元格内容 判断如果与上一次循环取得的内容相同时*/
if (that != null && $(this).html() == $(that).html()) {
/*为当前单元格添加 rowspan 属性*/
rowspan = $(that).attr("rowSpan");
/* 如果不存在 rowspan 属性 则添加该属性,默认值为 1*/
if (rowspan == undefined) {
$(that).attr("rowSpan", 1);
rowspan = $(that).attr("rowSpan");
}
/* 如果已经存在 rowspan 属性,则值 + 1 */
rowspan = Number(rowspan) + 1;
$(that).attr("rowSpan", rowspan);
/* 隐藏当前单元格 */
$(this).hide();
} else {
/*第一次循环 或 单元格内容与上一次不同时 更新 that 的值*/
that = this;
}
});
});
/* 自调用 */
if (colIdx > 0) {
colIdx -= 1;
MergeCol_v1(tableid, colIdx);
}
}
合并后效果(第一次)
一眼望去,似乎效果不错。。。。
但是,这仅仅是个巧合。修改一下数据格式再看。
构造数据(第二次)
<table id="table">
<thead>
<tr>
<th>公司地点</th>
<th>部门名称</th>
<th>小组名称</th>
<th>项目名称</th>
<th>参与人员</th>
<th>备注信息</th>
</tr>
</thead>
<tbody>
<!-- tr td 就不贴代码了,占地方,只贴一下构造后的效果图吧 -->
</tbody>
</table>
构造后效果图(第二次)
再试试用第一次的代码合并
Oh !!!
显然,大多数情况下我们需要的并不是这种格式。尤其是想体现的是一种层级关系的时候。
所以,调整合并单元格的代码。
调整合并单元格的代码
$(function () {
MergeCol_v2('#table', 5);
})
/*表格合并列单元格,colIdx:要合并的前 n 列
* @param tableid 表ID,例如#Table_Center
* @param colIdx 列位置,前 colIdx 列
*/
function MergeCol_v2(tableid, colIdx) {
var that;
/**/
var _text = function (cols) {
return $.map(cols, function (col) {
return $(col).text();
}).join('**');
};
/* 遍历表格下所有行 */
$(tableid + ' tbody tr').each(function (row) {
/* 获取当前行前 colIdx 列 并过滤"不可见"元素(hidden、disabled 等)*/
var _colspan = $(this).find('td:lt(' + colIdx + ')').filter(':visible');
/* 如果存在可见列 */
if (_colspan.length > 0) {
/* 如果存在上一行内容 并且 当前行的前 colIdx 列的内容 与上一行的前 colIdx 列的内容 完全相同 */
if ((that != null && _text(_colspan) == _text(that))) {
/* 遍历前当前行的 前 colIdx 列 */
that.each(function (col) {
/* 获取当前遍历到的列的 rowSpan 属性 */
rowspan = $(this).attr("rowSpan");
/* 如果未定义 rowSpan 属性 */
if (rowspan == undefined) {
/* 对当前单元格添加 rowSpan 属性,默认值为 1 */
$(this).attr("rowSpan", 1);
rowspan = $(this).attr("rowSpan");
}
/* 如果当前单元格已存在 rowSpan 属性 ,则对 rowspan 的值加上之前合并过的 rowspan 的值(默认 为 1)*/
rowspan = Number(rowspan) + (Number($(_colspan).attr("rowSpan") || 1));
$(this).attr("rowSpan", rowspan);
})
/* 遍历之前判断的内容相同的列,依次隐藏 */
$(_colspan).each(function (col) {
$(this).hide();
})
} else {
/* 如果不存在上一行内容(第一行)*/
that = _colspan;
}
}
});
/* 自调用 */
if (colIdx > 0) {
colIdx -= 1;
MergeCol_v2(tableid, colIdx);
}
}
合并后效果(第二次)