继续表格的有关操作,这篇说说表格行与列的删除。
所有这些操作恼人的地方其实都是在融合的单元格上
a.行的移除
首先计算整个表格的总列数。
var $row = $(sender).parent().parent();
var $nextRow = $row.next();
var $firstRow = $row.parent().children( " tr:first " );
var colCount = $firstRow.children( " td " ).size();
$firstRow.children( " td[colspan] " ).each( function () {
colCount = colCount + ($( this ).attr( " colspan " ) - 1 );
}); // 表格总列数
然后是当前这一行被行融合所占去的列数,
var count = colCount - $row.children().size();
$row.children( " td[colspan] " ).each( function () {
count = count - ($( this ).attr( " colspan " ) - 1 );
}); // 被行融合被占用的单元格数目
如果当前行没有被行融合占掉的就好说了,如果有的话要把父节点的rowspan值减1,先贴代码吧。
if (count > 0 ) { // 当前行有位置被行合并单元格占用的,要往上溯把相应的rowspan值减1
var $preRow = $row.prev();
var spanClsName = "" ;
while ($preRow) {
var spanColumn = $preRow.children( " td[rowspan] " ).get();
for ( var i = 0 ; i < spanColumn.length; i ++ ) {
var $ this = $(spanColumn[i]);
if (spanClsName.length > 0 && spanClsName <= $ this .attr( " class " ))
break ;
var spanCount = $ this .attr( " rowspan " );
spanCount = spanCount - 1 ;
if (spanCount == 1 )
$ this .removeAttr( " rowspan " );
else
$ this .attr( " rowspan " , spanCount);
var colSpan = $ this .attr( " colspan " );
if (colSpan)
count = count - colSpan;
else
count = count - 1 ;
if (count == 0 )
break ;
}
if (count == 0 )
break ;
if (spanColumn.length > 0 )
spanClsName = $(spanColumn[ 0 ]).attr( " class " );
$preRow = $preRow.prev();
}
}
最终把count归零就表示把所有父节点的rowspan值都减1了。
里面那个循环,
var spanColumn = $preRow.children("td[rowspan]").get();
for (var i = 0; i < spanColumn.length; i++) {
}
这里为什么不用jquery的each,而用js原始形态的for,是为了避免把兄弟节点的rowspan值也减1。
接下来,考虑当前行有行融合单元格的,把rowspan值减1,加入到下一行中,这里也用了循环,而且是递减的,是为了把节点以正确的顺序加入到下行的行首
var spanRows = $row.children( " td[rowspan] " ).get(); // 当前行有行合并单元格的,要把rowspan值减1,并加入到下一行
for ( var i = spanRows.length - 1 ;i >= 0 ;i -- ){
var $ this = $(spanRows[i]);
var spanCount = $ this .attr( " rowspan " );
spanCount = spanCount - 1 ;
if (spanCount == 1 )
$ this .removeAttr( " rowspan " );
else
$ this .attr( " rowspan " , spanCount);
$ this .insertBefore($nextRow.children( " td:first " ));
};
最后把当前行移除
$row.remove(); //当前行移除
b.列的移除
列的移除思路也跟行移除一样,先找父代的colspan的节点;当前列如果是融合的,colspan值减1,加入到下一列(注:这里加入到下一列只是把class改为下一列的class而已)。
var $column = $(sender).parent();
var className = $column.attr( " class " );
var nextClass = $column.next().attr( " class " );
var $row = $column.parent();
var $table = $row.parent();
var opIndex = $table.children( " tr " ).index($row);
var ri = 0 ;
var $chCol, $pchCol;
取操作符所在行的行索引,是为了寻当前列的单元格时有一个终止条件。
while (ri < opIndex) {
var $cRow = $table.children( " tr " ).eq(ri);
$chCol = $cRow.children( " td. " + className);
if ($chCol.size() == 0 ) {
// ......当前行当前列,没有相应单元格,往左找它的融合单元格
} else {
// ......当前行当前列,有单元格存在
}
}
当前列没有单元格时,用操作符列的class来回溯找融合单元格
var $preColumn = $column.prev();
var preClassName = $preColumn.attr( " class " );
$pchCol = $cRow.children( " td. " + preClassName);
while ($pchCol.size() == 0 ) { // 这个位置上没有单元格位置,找它的融合单元格
$preColumn = $preColumn.prev();
preClassName = $preColumn.attr( " class " );
$pchCol = $cRow.children( " td. " + preClassName);
}
var spanCount = $pchCol.attr( " colspan " ); // 相应的colspan值减1
spanCount -- ;
if (spanCount == 1 )
$pchCol.removeAttr( " colspan " );
else
$pchCol.attr( " colspan " , spanCount);
var rSp = $pchCol.attr( " rowspan " ); // 跳过行融合的单元格
if (rSp && rSp > 1 )
ri += rSp;
else
ri ++ ;
var $ this = $chCol.eq( 0 );
var spanCount = $ this .attr( " colspan " ); // 当前单元格是融合的
if (spanCount && spanCount > 1 ) {
spanCount -- ;
if (spanCount > 1 )
$ this .attr( " colspan " , spanCount);
else
$ this .removeAttr( " colspan " );
$ this .attr( " class " , nextClass); // colspan值减1后加到后面一列去
}
var rSp = $ this .attr( " rowspan " );
if (rSp && rSp > 1 )
ri += rSp;
else
ri ++ ;
最后把这一列移除
$("td." + className).each(function() {
$(this).remove();
});