`
chenhua_1984
  • 浏览: 1231700 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

js操作html的table,包括添加行,添加列,删除行,删除列,合并单元格(未实现)

阅读更多

       记得以前面试的时候遇到过这样一个问题:有一个表格,然后有4个输入框,一个合并 按钮,输入框是这样的,从第几行到第几行,从第几列到第几列,然后点击按钮,合并 。当时我从学校出来,js知识只是知道一些,根本做不到!现在想想,其实这个问题也还是考基础功夫是否扎实!大家有兴趣可以自己做做看,测下自己是不是能够做出来。题目的截图:

 

第1/1列 第1/2列 第1/3列 第1/4列 第1/5列
第2/1列 第2/2列 第2/3列 第2/4列 第2/5列
第3/1列 第3/2列 第3/3列 第3/4列 第3/5列
第4/1列 第4/2列 第4/3列 第4/4列 第4/5列
第5/1列 第5/2列 第5/3列 第5/4列 第5/5列
第6/1列 第6/2列 第6/3列 第6/4列 第6/5列
第7/1列 第7/2列 第7/3列 第7/4列 第7/5列
第8/1列 第8/2列 第8/3列 第8/4列 第8/5列
第9/1列 第9/2列 第9/3列 第9/4列 第9/5列
从第 行到 行

从第 列到 列

 

     现在做这个问题,看起来简单,但我还是花了很长时间,可能是我的思路不对吧?主要就是用js来操作html,我现在实现了添加行,删除行,添加列,删除列 ,但合并单元格却不能完整的实现主要是表格会乱掉 。现在把这个问题发出来,有兴趣的同仁可以自己在有空的时候研究下,看自己能不能做出来!主要是合并单元格的问题!也可以帮我看看合并单元格的问题。

 我自己实现的部分代码:

html部分 写道
<body onLoad="init();">

<table id="table" align="center">
<tbody id="newbody"></tbody>

</table>
<div>
<table width="800px" border="1px" align="center">
  <tr><td align="center"><input type="button" id="addRow" name="addRow" onClick="addRow();" value="添加行"/></td>
    <td align="center"><input type="button" id="delRow" name="delRow" onClick="removeRow();" value="删除行"/></td>
  </tr>
  <tr><td align="center"><input type="button" id="delCell" name="delCell" onClick="removeCell();" value="删除列"/></td>
    <td align="center"><input type="button" id="addCell" name="addCell" onClick=" addCell();" value="添加列"/></td>
 </tr>
 <tr><td align="center" colspan="2"><input type="button" id="addRows" name="addRows" onClick="addRow_withInsert();" value="添加行"/></td></tr>
</table>
</div>
<div>
<table width="800px" border="1px" align="center">
   <tr><td>从第<input type="text" id="beginRow" name="beginRow" value=""/> 行到   <input type="text" name="endRow" id="endRow" value=""/> 行</td><td rowspan="2" id="test"><input type="button" name="hebing" id="hebing" value="合并" onClick="rebulid();"/> </td></tr>
  <tr><td>从第<input type="text" name="beginCol" id="beginCol" value=""/> 列到<input type="text" name="endCol" id="endCol" value=""/> 列</td></tr>
</table>
</div>
</body>
 
生成表格,采用appendChild 写道
function init(){
_table=document.getElementById ("table");
_table.border="1px";
_table.width="800px";

for(var i=1;i<10;i++){
  var row=document.createElement ("tr");
  row.id=i;
  for(var j=1;j<6;j++){
   var cell=document.createElement ("td");
   cell.id =i+"/"+j;
   cell.appendChild(document.createTextNode ("第"+cell.id+"列"));
   row.appendChild (cell);
  }
  document.getElementById("newbody").appendChild (row);
 }
}
 
添加行,使用appendChild方法 写道
function addRow(){
var length=document.getElementById("table").rows.length;
/*document.getElementById("newbody").insertRow(length);
  document.getElementById(length+1).setAttribute("id",length+2);*/
  var tr=document.createElement("tr");
  tr.id=length+1;
  var td=document.createElement("td");

  for(i=1;i<4;i++){
    td.id=tr.id+"/"+i;
    td.appendChild(document.createTextNode("第"+td.id+"列"));
    tr.appendChild(td);

  }

  document.getElementById("newbody").appendChild (tr);
}
 
添加行的另一种方法insertRow 写道
function addRow_withInsert(){
   varrow=document.getElementById("table").insertRow( document.getElementById("table").rows.length);
 var rowCount =document.getElementById("table").rows.length;

 var countCell=document.getElementById("table").rows.item(0).cells.length;
 for(var i=0;i<countCell;i++){
   var cell=row.insertCell(i);

   cell.innerHTML="新"+(rowCount)+"/"+(i+1)+"列";
   cell.id=(rowCount)+"/"+(i+1);

  }

}
 
删除行,采用deleteRow(row Index) 写道
/*删除行,采用deleteRow(row Index)*/
function removeRow(){
/* var row=document.getElementById("2");
  var index=row.rowIndex;
  alert(index);*/
   document.getElementById("newbody").deleteRow(document.getElementById(document.getElementById("table").rows.length).rowIndex);
}
 
添加列,采用insertCell(列位置)方法 写道
function addCell(){
/*document.getElementById("table").rows.item(0).cells.length
用来获得表格的列数
*/
for(var i=0;i<document.getElementById("table").rows.length;i++){
  var cell=document.getElementById("table").rows[i].insertCell(2);
  cell.innerHTML="第"+(i+1)+"/"+3+"列";

}

}
 
删除列,采用deleteCell(列位置)的方法 写道
/*删除列,采用deleteCell(列位置)的方法*/
function removeCell(){
  for(var i=0;i<document.getElementById("table").rows.length;i++){
    document.getElementById("table").rows[i].deleteCell(0);
  }
}
 
合并单元格(未实现) 写道
我的代码有问题,主要是表格会乱掉,一直没有改好
function rebulid(){
var beginRow=document.getElementById("beginRow").value;/*开始行*/
var endRow=document.getElementById("endRow").value;/*结束行*/

var beginCol=document.getElementById("beginCol").value;/*开始列*/
var endCol=document.getElementById("endCol").value;/*结束列*/

var tempCol=beginRow+"/"+beginCol;/*定位要改变属性的列*/
alert(tempCol);
var td=document.getElementById(tempCol);

/*删除要合并的单元格*/
for(var x=beginRow;x<=endRow;x++){
  for(var i=beginCol;i<=endCol;i++){
    if(x==beginRow){

      document.getElementById("table").rows[x].deleteCell(i+1);

    }
    else{

      document.getElementById("table").rows[x].deleteCell(i);

    }

   }
  }
   td.rowSpan=(endRow-beginRow)+1;
}
 

分享到:
评论
36 楼 mingyuan0824 2009-09-20  
这个东西作出来维护太费劲了,去年公司要开发一个WEB版的EXCEL当时刚刚接触JS,写了整整4各月才弄完,号要求能在线编辑表格,存成报表的格式。什么合并拆分单元格啊,函数,多个表合成一个报表什么的。提供实时存储。字体,边框样式、范围选择什么的,功能一大堆,不让使用任何框架,后来发现维护很困难,过段时间在看,逻辑关系自己都忘记了。不过只能兼容IE。
35 楼 shuaijie506 2009-09-18  
我对js操作TABLE比较熟悉,经常使用。
其实合并和拆分单元格的技术并不复杂,最关键的是用户的使用体验上,和Excel的体验差远了,所以我没有专门做过类似Excel的功能。
关于操作单元格,有一个地方需要注意,那就是行号和列号,因为有合并单元格的情况出现,所以用tbl.rows[i].cells[j]并不能取到第i行第j列的单元格,我的方法是操作前对table的html对象建立单元格的一个二维数组,取第i行第j列的单元格直接用tbl.cells[i][j],在进行单元格操作时需要维护这个二维数组。其实如果真要开发这样的东西,可以自己建立一个JS对象,封装好对表格的操作,这样逻辑上更清晰一些。

行的操作:
合并,先用deleteCell删除第2个以及以后的TD,再修改第一个TD的rowSpan,这里需要注意的是不要从前往后删,最好是从后往前删,或者只删第N个,删M次,这样就达到了删除第N到第N+M个TD的目的了。(PS:看楼主的代码好像就犯了这个错)
拆分,更好做,修改RowSpan,再insertCell就行了。
至于列的操作,和行的操作是类似的。
34 楼 zjxingkongkk 2009-09-18  
楼主太强大了~~down下来看了之后才知道js真的这么强大
正好解决了一个大难题~~忽忽
33 楼 soni 2009-09-17  
楼上的想法和我类似,首先对于这类操作,一定要建立一个2维数组来保存表格的单元格。以后的操作根据这个矩阵来实现。
另外,补充一点,ie的colSpan属性太让人崩溃了。
32 楼 busy882376 2009-08-21  
js果然很强
31 楼 jdai84 2009-08-19  
正在找的一些东西。。谢谢楼主
30 楼 jejwe 2009-08-13  
<p> </p>
<pre name="code" class="js">var TableApi;
(function () {
    var MyDom = Helper.Dom;
    var MyCore = Helper.Core;

    TableApi = {
        /**
         * 获取table元素的单元格分布矩阵
         * @param table
         */
        getMatrix : function (table) {
            var matrix = [];
            for (var rowIndex = 0, rCnt = table.rows.length; rowIndex &lt; rCnt; rowIndex++) {
                if (!matrix[rowIndex]) {
                    matrix[rowIndex] = [];
                }
                for (var cellIndex = 0, cCnt = table.rows[rowIndex].cells.length; cellIndex &lt; cCnt; cellIndex++) {
                    var columnIndex = cellIndex;
//In case there's are any horizontal or vertical spans before this cell
                    while (matrix[rowIndex][columnIndex]) {
                        columnIndex++;
                    }

                    var cell = table.rows[rowIndex].cells[cellIndex];

//Fill the corresponding matrix points
                    for (var i = 0; i &lt; cell.rowSpan; i++) {
                        if (!matrix[rowIndex + i]) {
                            matrix[rowIndex + i] = [];
                        }
                        for (var j = 0; j &lt; cell.colSpan; j++) {
                            matrix[rowIndex + i][columnIndex + j] = cell;
                        }
                    }
                }
            }
            return matrix;
        },
        /**
         * 合并单元格分布矩阵中选中的单元格
         * @param matrix
         */
        merge : function (matrix) {
            var maxRowIndex = 0;
            var minRowIndex = matrix.length - 1;
            var maxColumnIndex = 0;
            var minColumnIndex = matrix[0].length - 1;

            var rowIndex, columnIndex, rCnt, cCnt;

        //decide if selected cells region is mergable
            for (rowIndex = 0,rCnt = matrix.length; rowIndex &lt; rCnt; rowIndex++) {
                for (columnIndex = 0,cCnt = matrix[0].length; columnIndex &lt; cCnt; columnIndex++) {
                    if ($(matrix[rowIndex][columnIndex]).hasClass('selected')) {
                        if (rowIndex &gt; maxRowIndex) {
                            maxRowIndex = rowIndex;
                        }
                        if (rowIndex &lt; minRowIndex) {
                            minRowIndex = rowIndex;
                        }
                        if (columnIndex &gt; maxColumnIndex) {
                            maxColumnIndex = columnIndex;
                        }
                        if (columnIndex &lt; minColumnIndex) {
                            minColumnIndex = columnIndex;
                        }
                    }
                }
            }

            var mergable = true;
            for (rowIndex = minRowIndex; rowIndex &lt;= maxRowIndex &amp;&amp; mergable; rowIndex++) {
                for (columnIndex = minColumnIndex; columnIndex &lt;= maxColumnIndex; columnIndex++) {
                    if (!$(matrix[rowIndex][columnIndex]).hasClass('selected')) {
                        mergable = false;
                        break;
                    }
                }
            }

            if (mergable) {
                //then merge
                var cellToMergeInto = matrix[minRowIndex][minColumnIndex];
                for (rowIndex = minRowIndex; rowIndex &lt;= maxRowIndex; rowIndex++) {
                    for (columnIndex = minColumnIndex; columnIndex &lt;= maxColumnIndex; columnIndex++) {
                        var cell = matrix[rowIndex][columnIndex];
                        if (cell !== cellToMergeInto) {
                            for (var i = 0; i &lt; cell.rowSpan; i++) {
                                for (var j = 0; j &lt; cell.colSpan; j++) {
                                    matrix[rowIndex + i][columnIndex + j] = cellToMergeInto;
                                }
                            }
                            MyDom.removeEl(cell);
                        }
                    }
                }

                cellToMergeInto.colSpan = (maxColumnIndex - minColumnIndex) + 1;
                cellToMergeInto.rowSpan = (maxRowIndex - minRowIndex) + 1;

                this.cleanUpEmptyRowsAndColumns(matrix);
            }

            return mergable;
        },
        /**
         * 在单元格分布矩阵中指定行中搜索指定列的前一个单元格
         * @param matrix
         * @param rowIndex
         * @param columnIndex
         */
        searchForPreviousCellInRow : function (matrix, rowIndex, columnIndex) {
            var columnIndexForPreviousCell = columnIndex;
            var previousCell = null;
            do{
                columnIndexForPreviousCell -= 1;
                previousCell = matrix[rowIndex][columnIndexForPreviousCell];
            }
            while (previousCell &amp;&amp; (previousCell.parentNode.rowIndex !== rowIndex));

            return previousCell;
        },
        /**
         * 还原合并的单元格
         * @param cell
         */
        revertMerged : function (cell) {
            var table = MyDom.searchUpByTagName(cell, 'TABLE');
            var matrix = this.getMatrix(table);
            var rowIndex = cell.parentNode.rowIndex;
            var columnIndex = matrix[rowIndex].indexOf(cell);
            var jCell = $(cell);

            var tableApi = this;

            MyCore.repeat(cell.colSpan - 1, function () {
                jCell.after('&lt;td&gt;');
            });

            MyCore.repeat(cell.rowSpan - 1, function (time) {
                var previousCell = tableApi.searchForPreviousCellInRow(matrix, rowIndex + time, columnIndex);

                var task = null;
                if (previousCell) {
                    var jPreviousCell = $(previousCell);
                    task = function () {
                        jPreviousCell.after('&lt;td&gt;');
                    };
                }
                else {
                    var jRow = $(table.rows[rowIndex + time]);
                    task = function () {
                        jRow.prepend('&lt;td&gt;');
                    };
                }

                MyCore.repeat(cell.colSpan, task);
            });

            cell.colSpan = cell.rowSpan = 1;
        },
        /**
         * 清理单元格分布矩阵中的空行空列
         * @param matrix
         * @requires the matrix must reflect the current state of the table
         */
        cleanUpEmptyRowsAndColumns : function (matrix) {
            var table = matrix[0][0].parentNode.parentNode.parentNode;

            var rowIndex, columnIndex, cell, cellToCollapse&lt;script src="/javascripts/tinymce/themes/advanced/langs/zh.js" type="text/javascript"&gt;&lt;!--mce:0--&gt;&lt;/script&gt;&lt;script src="/javascripts/tinymce/plugins/javaeye/langs/zh.js" type="text/javascript"&gt;&lt;!--mce:1--&gt;&lt;/script&gt;, rCnt, cCnt;

            cCnt = matrix[0].length;
            //clean up empty rows
            for (rowIndex = 0,rCnt = matrix.length; rowIndex &lt; rCnt; rowIndex++) {
                var isEmptyRow = true;
                for (columnIndex = 0; columnIndex &lt; cCnt; columnIndex++) {
                    cell = matrix[rowIndex][columnIndex];
                    if (cell.rowSpan === 1 || cell.parentNode.rowIndex === rowIndex) {
                        isEmptyRow = false;
                        break;
                    }
                }
                if (!isEmptyRow) {
                    continue;
                }

//recalculate the rowspan
                columnIndex = 0;
                do{
                    cellToCollapse = matrix[rowIndex][columnIndex];
                    cellToCollapse.rowSpan -= 1;
                    columnIndex += cellToCollapse.colSpan;
                }
                while (columnIndex &lt; cCnt);

//remove empty tr element
                var row = table.rows[rowIndex];
                MyDom.removeEl(row);

//remove empty row from matrix
                for (var i = rowIndex, iLen = rCnt - 1; i &lt; iLen; i++) {
                    matrix[i] = matrix[i + 1];
                }
                matrix.length -= 1;
                rCnt--;

            //cuz the original next row is now the current row
                rowIndex--;
            }

//clean up empty columns
            for (columnIndex = 0; columnIndex &lt; cCnt; columnIndex++) {
                var isEmptyColumn = true;
                for (rowIndex = 0; rowIndex &lt; rCnt; rowIndex++) {
                    cell = matrix[rowIndex][columnIndex];
                    if (cell.colSpan === 1 || matrix[rowIndex][columnIndex + cell.colSpan - 1] === cell) {
                        isEmptyColumn = false;
                        break;
                    }
                }

                if (!isEmptyColumn) {
                    continue;
                }

//recalculate the colspan
                rowIndex = 0;
                do{
                    cellToCollapse = matrix[rowIndex][columnIndex];
                    cellToCollapse.colSpan -= 1;
                    rowIndex += cellToCollapse.rowSpan;
                }
                while (rowIndex &lt; rCnt);

//remove empty column from matrix
                for (rowIndex = 0; rowIndex &lt; rCnt; rowIndex++) {
                    for (var j = columnIndex, jLen = cCnt - 1; j &lt; jLen; j++) {
                        matrix[rowIndex][j] = matrix[rowIndex][j + 1];
                    }
                    matrix[rowIndex].length -= 1;
                }
                cCnt--;

            //remove corresponding col from colgroup if one exists
                var colGroup = $('colgroup', table).get(0);
                if (colGroup &amp;&amp; colGroup.parentNode === table) {
                    MyDom.removeEl($('col:eq(' + columnIndex + ')', colGroup).get(0));
                }

//cuz the original next column is now the current column
                columnIndex--;
            }
        },
        /**
         * 根据指定的单元格和坐标获取在单元格分布矩阵中的精确位置
         * @param matrix
         * @param cell
         * @param pageX
         * @param pageY
         */
        getAccuratePositionInMatrix : function (matrix, cell, pageX, pageY) {
            var rowIndex = -1;
            var columnIndex = -1;

            var found, i, j, jCell, offset, iLen;

            if (cell.colSpan === 1) {
                columnIndex = matrix[cell.parentNode.rowIndex].indexOf(cell);
            }
            else {
                var firstApperanceColumnIndex = matrix[cell.parentNode.rowIndex].indexOf(cell);
                found = false;

//search for a single-column cell within the same column as the multi-column cell, which cuts through pageX horizontally.
                for (j = firstApperanceColumnIndex; !found &amp;&amp; j &lt; firstApperanceColumnIndex + cell.colSpan; j++) {
                    for (i = 0,iLen = matrix.length; i &lt; iLen; i++) {
                        if (matrix[i][j].colSpan !== 1) {
                            continue;
                        }

                        jCell = $(matrix[i][j]);
                        offset = jCell.offset();
                        if (offset.left &lt;= pageX &amp;&amp; offset.left + jCell.width() &gt;= pageX) {
                            columnIndex = j;
                            found = true;
                        }
                        break;
                    }
                }

                if (!found) {
                    columnIndex = firstApperanceColumnIndex;
                }
            }

            if (cell.rowSpan === 1) {
                rowIndex = cell.parentNode.rowIndex;
            }
            else {
                found = false;
                var jLen = matrix[0].length;
            //search for a single-row cell within the same row as the multi-row cell, which cuts through pageY vertically.
                for (i = cell.parentNode.rowIndex; !found &amp;&amp; i &lt; cell.parentNode.rowIndex + cell.rowSpan; i++) {
                    for (j = 0; j &lt; jLen; j++) {
                        if (matrix[i][j].rowSpan !== 1) {
                            continue;
                        }

                        jCell = $(matrix[i][j]);
                        offset = jCell.offset();
                        if (offset.top &lt;= pageY &amp;&amp; offset.top + jCell.height() &gt;= pageY) {
                            rowIndex = i;
                            found = true;
                        }
                        break;
                    }
                }

                if (!found) {
                    rowIndex = cell.parentNode.rowIndex;
                }
            }

            return {
                rowIndex : rowIndex,
                columnIndex : columnIndex
            };
        },
        /**
         * 重设列宽度
         * @param table
         * @param columnIndex
         * @param width
         */
        resizeColumn : function (table, columnIndex, width) {
            //Notice that IE6 has problem with applying column width solely by col element. Set table-layout to fixed will solve this problem.
            $('colgroup:first col:eq(' + columnIndex + ')', table).css('width', width);
        },
        /**
         * 重设行高度
         * @param table
         * @param rowIndex
         * @param height
         */
        resizeRow : function (table, rowIndex, height) {
            $('tbody:eq(0) &gt; tr:eq(' + rowIndex + ')', table).css('height', height);
        },
        /**
         * 计算获得table元素的行和列的位置偏移量
         * @param matrix
         */
        getOffsetsToTableForColumnAndRow : function (matrix) {
            var columnOffsets = []; // the offset for the left edge of the columns
            var rowOffsets = []; //the offset for the top edge of the rows

            var tableOffset = $(MyDom.searchUpByTagName(matrix[0][0], 'TABLE')).offset();

            var cell;

            var
                    rCnt = matrix.length,
                    cCnt = matrix[0].length;
            for (var rowIndex = 0; rowIndex &lt; rCnt; rowIndex++) {
                for (var columnIndex = 0; columnIndex &lt; cCnt; columnIndex++) {
                    if (!columnOffsets[columnIndex]) {
                        cell = matrix[rowIndex][columnIndex];
                        if (cell.colSpan === 1 || matrix[rowIndex][columnIndex + cell.colSpan - 1] === cell) {
                            columnOffsets[columnIndex] = $(cell).offset().left - tableOffset.left;
                        }
                    }

                    if (!rowOffsets[rowIndex]) {
                        cell = matrix[rowIndex][columnIndex];
                        if (cell.rowSpan === 1 || cell.parentNode.rowIndex === rowIndex) {
                            rowOffsets[rowIndex] = $(cell).offset().top - tableOffset.top;
                        }
                    }
                }
            }

            return {
                columnOffsets : columnOffsets,
                rowOffsets : rowOffsets
            };
        },
        /**
         * 在单元格所在列右边插入新列
         * @param cell
         * @param width
         */
        insertColumnAfterCell : function (cell, width) {
            var table = MyDom.searchUpByTagName(cell, 'TABLE');
            var matrix = this.getMatrix(table);
            var columnIndex = matrix[cell.parentNode.rowIndex].indexOf(cell) + cell.colSpan - 1;

//if the current column isn't the last column
            if (columnIndex &lt; matrix[0].length - 1) {
                for (var rowIndex = 0, rCnt = matrix.length; rowIndex &lt; rCnt; rowIndex++) {
                    var currentCell = matrix[rowIndex][columnIndex];

                    if (currentCell !== matrix[rowIndex][columnIndex + 1]) {
                        $(currentCell).after('&lt;td&gt;');

                        for (var i = 1; i &lt; currentCell.rowSpan; i++) {
                            var previousCell = this.searchForPreviousCellInRow(matrix, rowIndex + i, columnIndex);

                            if (previousCell) {
                                $(previousCell).after('&lt;td&gt;');
                            }
                            else {
                                $(table.rows[rowIndex + i]).prepend('&lt;td&gt;');
                            }
                        }
                    }
                    else {
                        currentCell.colSpan++;
                    }

                    rowIndex += currentCell.rowSpan - 1;
                }
            }
            else {
                MyCore.each(table.rows, function (row) {
                    $(row).append('&lt;td&gt;');
                });
            }

            $('col:eq(' + columnIndex + ')', table).after('&lt;col style="width:' + width + 'px" /&gt;');
        },
        /**
         * 在单元格所在列左边插入新列
         * @param cell
         * @param width
         */
        insertColumnBeforeCell : function (cell, width) {
            var table = MyDom.searchUpByTagName(cell, 'TABLE');
            var matrix = this.getMatrix(table);
            var columnIndex = matrix[cell.parentNode.rowIndex].indexOf(cell);

//if the current column isn't the first column
            if (columnIndex &gt; 0) {
                for (var rowIndex = 0, rCnt = matrix.length; rowIndex &lt; rCnt; rowIndex++) {
                    var currentCell = matrix[rowIndex][columnIndex];

                    if (currentCell !== matrix[rowIndex][columnIndex - 1]) {
                        $(currentCell).before('&lt;td&gt;');

                        for (var i = 1; i &lt; currentCell.rowSpan; i++) {
                            var previousCell = this.searchForPreviousCellInRow(matrix, rowIndex + i, columnIndex);

                            if (previousCell) {
                                $(previousCell).after('&lt;td&gt;');
                            }
                            else {
                                $(table.rows[rowIndex + i]).prepend('&lt;td&gt;');
                            }
                        }
                    }
                    else {
                        currentCell.colSpan++;
                    }

                    rowIndex += currentCell.rowSpan - 1;
                }
            }
            else {
                MyCore.each(table.rows, function (row) {
                    $(row).prepend('&lt;td&gt;');
                });
            }

            $('col:eq(' + columnIndex + ')', table).before('&lt;col style="width:' + width + 'px" /&gt;');
        },
        /**
         * 在单元格所在行下面插入新行
         * @param cell
         * @param height
         */
        insertRowBelowCell : function (cell, height) {
            var table = MyDom.searchUpByTagName(cell, 'TABLE');
            var matrix = this.getMatrix(table);
            var rowIndex = cell.parentNode.rowIndex + cell.rowSpan - 1;

            var newRow = '&lt;tr style="height:' + height + 'px"&gt;';

            if (rowIndex &lt; matrix.length - 1) {
                for (var columnIndex = 0, cCnt = matrix[rowIndex].length; columnIndex &lt; cCnt; columnIndex++) {
                    var currentCell = matrix[rowIndex][columnIndex];
                    if (currentCell !== matrix[rowIndex + 1][columnIndex]) {
                        MyCore.repeat(currentCell.colSpan, function () {
                            newRow += '&lt;td&gt;&lt;/td&gt;';
                        });
                    }
                    else {
                        currentCell.rowSpan++;
                    }

                    columnIndex += currentCell.colSpan - 1;
                }
            }
            else {
                MyCore.repeat(matrix[rowIndex].length, function () {
                    newRow += '&lt;td&gt;&lt;/td&gt;';
                });
            }

            newRow += '&lt;/tr&gt;';

            $(table.rows[rowIndex]).after(newRow);
        },
        /**
         * 在单元格所在行上面插入新行
         * @param cell
         * @param height
         */
        insertRowAboveCell : function (cell, height) {
            var table = MyDom.searchUpByTagName(cell, 'TABLE');
            var matrix = this.getMatrix(table);
            var rowIndex = cell.parentNode.rowIndex;

            var newRow = '&lt;tr style="height:' + height + 'px"&gt;';

            if (rowIndex &gt; 0) {
                for (var columnIndex = 0, cCnt = matrix[rowIndex].length; columnIndex &lt; cCnt; columnIndex++) {
                    var currentCell = matrix[rowIndex][columnIndex];
                    if (currentCell !== matrix[rowIndex - 1][columnIndex]) {
                        MyCore.repeat(currentCell.colSpan, function () {
                            newRow += '&lt;td&gt;&lt;/td&gt;';
                        });
                    }
                    else {
                        currentCell.rowSpan++;
                    }

                    columnIndex += currentCell.colSpan - 1;
                }
            }
            else {
                MyCore.repeat(matrix[rowIndex].length, function () {
                    newRow += '&lt;td&gt;&lt;/td&gt;';
                });
            }

            newRow += '&lt;/tr&gt;';

            $(table.rows[rowIndex]).before(newRow);
        },
        /**
         * 按照源table的尺寸更新目标table
         * @param srcTable
         * @param targetTable
         */
        copySize : function (srcTable, targetTable) {
            var targetCols = $('colgroup:first col', targetTable).get();
            $('colgroup:first col', srcTable).each(function (index) {
                targetCols[index].style.width = this.style.width;
            });

            var targetRows = $('tbody:first tr', targetTable).get();
            $('tbody:first tr', srcTable).each(function (index) {
                targetRows[index].style.height = this.style.height;
            });
        },
        /**
         * 移除单元格所在的行
         * @param cell
         */
        removeRow : function (cell) {
            if (cell.rowSpan !== 1) {
                throw 'The cell has to only belong to one row!';
            }

            var table = MyDom.searchUpByTagName(cell, 'TABLE');

            if (table.rows.length === 1) {
                throw '这是表中唯一的一行,不允许删除!';
            }

            var matrix = this.getMatrix(table);

            var rowIndex = cell.parentNode.rowIndex;

            for (var columnIndex = 0, cCnt = matrix[rowIndex].length; columnIndex &lt; cCnt; columnIndex++) {
                var currentCell = matrix[rowIndex][columnIndex];
                if (currentCell.rowSpan &gt; 1) {
                    currentCell.rowSpan -= 1;

                    if (currentCell.parentNode.rowIndex === rowIndex) {
                        var cellToInsertAfter = null;
                        for (var columnIndexOfTheRowBelow = columnIndex - 1; columnIndexOfTheRowBelow &gt;= 0; columnIndexOfTheRowBelow--) {
                            var cellOfTheRowBelow = matrix[rowIndex + 1][columnIndexOfTheRowBelow];
                            if (cellOfTheRowBelow.rowSpan === 1 || cellOfTheRowBelow.parentNode.rowIndex === rowIndex + 1) {
                                cellToInsertAfter = cellOfTheRowBelow;
                                break;
                            }
                        }

                        var rowBelow = currentCell.parentNode.nextSibling;
                        if (cellToInsertAfter) {
                            rowBelow.insertBefore(currentCell, cellToInsertAfter.nextSibling);
                        }
                        else {
                            rowBelow.insertBefore(currentCell, rowBelow.firstChild);
                        }
                    }
                }

                columnIndex += currentCell.colSpan - 1;
            }

            MyDom.removeEl(table.rows[rowIndex]);

            this.cleanUpEmptyRowsAndColumns(this.getMatrix(table));
        },
        /**
         * 移除单元格所在的列
         * @param cell
         */
        removeColumn : function (cell) {
            if (cell.colSpan !== 1) {
                throw 'The cell has to only belong to one column!';
            }

            var table = MyDom.searchUpByTagName(cell, 'TABLE');

            var matrix = this.getMatrix(table);
            if (matrix[0].length === 1) {
                throw '这是该表唯一的一列,不允许删除!';
            }

            var columnIndex = matrix[cell.parentNode.rowIndex].indexOf(cell);

            for (var rowIndex = 0, rCnt = matrix.length; rowIndex &lt; rCnt; rowIndex++) {
                var currentCell = matrix[rowIndex][columnIndex];
                if (currentCell.colSpan &gt; 1) {
                    currentCell.colSpan -= 1;
                }
                else {
                    MyDom.removeEl(currentCell);
                }

                rowIndex += currentCell.rowSpan - 1;
            }

            MyDom.removeEl($('colgroup:first col:eq(' + columnIndex + ')', table).get(0));

            this.cleanUpEmptyRowsAndColumns(this.getMatrix(table));
        }
    };
})();
</pre>
29 楼 leisure 2009-06-15  
本人最近也在做一个在线编辑器中画table功能,比楼主的复杂得多。
比如在经过多次拆分合并后的一个单元格中 再次进行增删功能

现在剩下 选择多个单元格合并未实现

封装啊 封装 楼主代码需要封装啊
28 楼 whaosoft 2009-06-14  
我们现在的项目也有这个功能是挺恶心的
27 楼 wy19280469 2009-06-14  
你所写的东西网上已经有源代码了?去找找看,操作单元格!~ 你所说的所有功能都有 ....
26 楼 iampurse 2009-06-08  
请看merge 里头的操作。
25 楼 iampurse 2009-06-08  
var $ = jQuery;
var TBar = {
crt : function() {
var row = $('#row').val();
var col = $('#col').val();
$('#info table').remove();
var table = $("<table class='datalist form' cellspacing='0'></table>");
while (row-- > 0) {
var tr = $("<tr></tr>");
var num = col;
while (num-- > 0) {
tr.append("<td></td>");
}
table.append(tr);
}
$('#info').append(table);
App.initTd();
},
addRow : function() {

var tr = $('#info table tr:last').clone();
tr.find("td").html("");
App.initTd(tr.find("td"));
$('#info table').append(tr);
},
addCol : function() {
$('#info table tr').append(App.initTd($("<td></td>")));
},

delRow : function() {
var elIds = [];
$(".hit").parent().children().each(function() {
elIds[elIds.length] = $(this).children().attr("elid");
});

// FIXME 合理的不?
$.ajax({

    url:'/c/wkf/delFormElement',
                type:'post',
                data:{elIds:elIds.join(",")},
                dataType:'json',
                success:function(rst){
                    if(rst.success===true){
                        $('.hit').parent().remove();
                        //更新模板
                        var tpl = TBar.getLayOut();
                        var formId = $('#formId').val();
                        updateFormTpl(formId, tpl);
                    }else{
                        alert('删除行失败');
                    }
                }
               
});

},
delCol : function() {
var elIds = [];
$(".hit").each(function() {
elIds[elIds.length] = $(this).children().attr("elid");
});

// FIXME 合理的不?
$.ajax({

    url:'/c/wkf/delFormElement',
                type:'post',
                data:{elIds:elIds.join(",")},
                dataType:'json',
                success:function(rst){
                    if(rst.success===true){
                        $('.hit').remove();
                        //更新模板
                        var tpl = TBar.getLayOut();
                        var formId = $('#formId').val();
                        updateFormTpl(formId, tpl);
                    }else{
                        alert('删除行失败');
                    }
                }
               
});
},
clear : function() {
$('.hit').text("");

},
merge : function() {
var num = $('.hit').length;
if (num < 2) {
alert("请至少选择两个单元格!");
} else {
var first = $('.hit:first');
var last = $('.hit:last');

var lFirst = first.attr('offsetLeft');
var lLast = last.attr('offsetLeft');

var First = first.attr('offsetTop');
var tLast = last.attr('offsetTop');

var diffX = lLast - lFirst;
var diffY = tLast - First;
var cfg = false;
if (diffX == 0) {
cfg = {
offert : 'offsetLeft',
len : lFirst,
span : 'rowSpan'
};
}
if (diffY == 0) {
cfg = {
offert : 'offsetTop',
len : First,
span : 'colSpan'
};
}

if (cfg) {
var flag = true;
if (num > 2) {
$('.hit').each(function() {
var offert = $(this).attr(cfg.offert);
if (offert != cfg.len) {
return flag = false;
}
return flag = true;
});
}
if (flag) {
$('.hit').not(first).remove();
first.attr(cfg.span, num);
} else {
alert("请选择相邻的单元格!");
}
}
}
},
getLayOut : function() {

var tb = $('#info').clone();

tb.find('td').removeClass("hit").each(function() {
var el = $('.el', this).attr('el');
if (el) {
$(this).text("${" + el + "}")
} else {
$(this).text("")
}
});
var layout = tb.html().replace(/ jQuery\d*="null"/g, '');
return layout;

}
}
24 楼 lobbychmd 2009-06-03  
增加行
$(Grid + ' tbody tr:first-child').clone().appendTo(Grid + ' tbody');
23 楼 ninecat 2009-06-03  
大概实现了一下合并单元格, 没实现合并已经被合并的单元格
22 楼 fcu 2009-06-03  
以前公司做设计的时候就是用TABLE来实现,合并,增加,删除,但是列移动没有实现,维护起来麻烦死了,后来用的DATAGGRID,和三方的GRID,楼主也找找看吧
21 楼 dragonboa 2009-06-03  
var row0 = document.getElementByID("tableID").insertRow(-1);//tableID--该table的ID;-1表示是在该行的下面插入一行;
var cell = row0.insertCell(-1);//增加一个td
cell.innerHTML = "<td><strong>姓名:</strong></td>";//设置td的内容
cell.align = "right";//td的属性
row0.insertCell(-1).innerHTML = "<td><label><input type=\"text\" id=\"\" size=\"25\"></label></td>";//下一个td

可以这样不断的加
最后就形成了一个table了


至于删除的话document.getElementByID("tableID").deleteRow(1)就可以了,这是删除第二行。
20 楼 chenhua_1984 2009-06-03  
keyboard2000 写道
还是用控件吧,从底层写起太烦,且兼容性不好

实际运用的过程中是不会重新写的,这里只是练练手!是我以前的一个面试题目!
19 楼 chenhua_1984 2009-06-03  
<div class="quote_title">pub10 写道</div>
<div class="quote_div">
<p>这个功能可以参考fckeditor代码,fck已经实现得很好了。具体可以看一下fck源码\internals\fcktablehandler.js</p>
<p> <img src="/upload/attachment/110239/19a3dac6-d72b-3a3a-a8cf-08db73db9a78.jpg" alt=""></p>
</div>
<p>恩,是的,谢谢提示!</p>
18 楼 keyboard2000 2009-06-03  
还是用控件吧,从底层写起太烦,且兼容性不好
17 楼 pub10 2009-06-02  
<p>这个功能可以参考fckeditor代码,fck已经实现得很好了。具体可以看一下fck源码\internals\fcktablehandler.js</p>
<p> <img src="/upload/attachment/110239/19a3dac6-d72b-3a3a-a8cf-08db73db9a78.jpg" alt=""></p>

相关推荐

Global site tag (gtag.js) - Google Analytics