表格行列的删除
继续表格的有关操作,这篇说说表格行与列的删除。
所有这些操作恼人的地方其实都是在融合的单元格上
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();
});