`
chenhua_1984
  • 浏览: 1254135 次
  • 性别: 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>

相关推荐

    JS 实现Table相同行的单元格自动合并示例代码

    需要注意的是,当自动合并单元格时,开发者应该考虑表格的可访问性和数据的逻辑性,确保合并操作不会导致数据解读错误或者损害表格结构的完整性。例如,如果一个表格是用于数据导出或者数据分析的,那么合并单元格...

    vue-easytable合并单元格

    在这个“vue-easytable合并单元格”的主题下,我们将深入探讨如何利用Vue Easytable实现表格中的单元格合并。 在传统的HTML表格中,合并单元格通常使用`&lt;td&gt;`的`colspan`和`rowspan`属性来完成,但在Vue Easytable...

    JS实现动态修改table及合并单元格的方法示例

    总的来说,JS实现动态修改table及合并单元格涉及的主要知识点包括: 1. DOM操作:通过`getElementById`获取元素,使用`rows`和`cells`属性遍历表格。 2. 遍历技巧:使用`for`循环遍历表格行和列,根据需求进行判断...

    layui table合并单元格.zip

    "layui table合并单元格.zip" 这个压缩包正是提供了关于如何在layui的表格中实现单元格合并的示例和资源。 首先,"layui table.txt" 文件可能包含了layui表格组件的基础用法和API介绍。layui的表格组件支持动态加载...

    原生JS实现HTML- TABLE 自动行合并插件

    类功能描述:该插件生成一个具有行合并的列表数据,合并例由开发者指定。 开发者提供已排序的数据列表以及需要合并行的列名即可,无需后端二次处理数据。 该类以纯原生JS编写,无需引入任何第三方库。 调用方法:...

    javascript万能table合并单元格,隐藏列 html版

    ### JavaScript 实现 HTML Table 单元格合并及隐藏列功能详解 #### 一、背景介绍 在处理 HTML 表格时,我们经常会遇到需要合并相同数据的单元格以及根据需求显示或隐藏某些列的情况。例如,在报表展示或者数据汇总...

    完美的table单元格合并js

    本js脚本完美的实现了table单元格的合并,合并后犹如交叉表的形式,非常完美,并在其中附带例子可以验证。

    table合并单元格的多种方法

    在表格(Table)设计中,有时我们需要合并单元格来达到特定的展示效果,例如创建标题行或列,或者为了美观和布局对齐。在HTML、CSS以及JavaScript中,都有多种方式可以实现单元格的合并。这里我们将详细探讨六种合并...

    JSP Table 单元格合并

    每次遍历时都会更新计数器 `count`,用于记录合并单元格所占据的行数。 ```javascript count++; ``` #### 三、JSP 示例代码解析 在 JSP 文件中,使用 `&lt;s:iterator&gt;` 标签来迭代列表,并为每个元素生成一个表格行...

    LayUiTable表单相同参数的单元格合并

    本话题聚焦于LayUI中的Table组件,特别是如何实现相同参数的单元格合并功能,这在展示数据时能有效提高信息的可读性和美观性。 LayUI Table的单元格合并功能,主要是通过`parseData`方法和自定义模板来实现的。当...

    将HtmlTable 导出为Execl文件,支持合并单元格、合并行,无需Office支持

    本项目提供了一个解决方案,它支持合并单元格和合并行,无需依赖Microsoft Office,这对于那些无法安装Office环境或者希望在服务器端执行此操作的用户来说,具有很高的实用价值。 首先,我们要理解HTML表格...

    table-rowspan表格自动合并单元格插件

    "table-rowspan表格自动合并单元格插件"是专为HTML表格设计的一种工具,它允许开发者通过简单的操作实现单元格的动态合并、添加和删除,极大地提升了用户界面的可读性和交互性。以下是对这个插件及相关知识点的详细...

    富文本编辑器以及表格操作,可拉伸单元格宽度、增加行、增加列、合并单元格

    用户可以选择多个单元格,然后执行“合并单元格”操作,以实现这一效果。 5. **其他表格操作**:除了上述基本功能,富文本编辑器可能还包括拆分单元格、调整行高、排序数据、设置边框样式和颜色等高级功能,以满足...

    列表多行多列合并单元格

    综上所述,实现列表多行多列合并单元格涉及到HTML表格的基本操作,以及JavaScript动态计算和设置`colspan`和`rowspan`属性。在开发过程中,还需要考虑交互性、响应式设计和性能优化,确保在各种环境下都能提供良好的...

    合并table的行

    本文将深入探讨如何实现“合并table的行”这一功能,以及其背后的原理与应用场景。 ### 合并table的行:原理与实现 在Web开发中,`&lt;table&gt;`元素用于显示数据的表格形式,而合并行的功能主要通过`&lt;td&gt;`或`&lt;th&gt;`标签...

    javascript操作table(增加/删除行/单元格)

    对表格的行和列进行插入/删除,并对每行添加行号

    javascript 万能table合并单元格 js版

    只要输入table的id,就可以自动合并单元格,只要上下相邻的单元格相同的,都会合并 html版比较好,点下面的 http://download.csdn.net/source/1276574

    jquery datatable 单元格合并

    通过Datatables的`drawCallback`或`initComplete`事件,在表格渲染完成后合并单元格。遍历预处理得到的合并信息,使用DOM操作修改表格结构。 ```javascript $('#example').DataTable({ // ...其他配置... ...

    利用js合并table相同内容单元格并js方式自动生成

    利用js合并table相同内容单元格并js方式自动生成,把文本内容复制进js中,应该就知道大概咋用了

    bootstrap-table导出合并单元格

    Bootstrap Table是一款基于...通过以上步骤,我们就能在使用Bootstrap Table时实现导出合并单元格的功能,提高数据展示的效率和质量。在实际开发中,可以根据项目需求调整和定制这些方法,以满足更复杂的需求。

Global site tag (gtag.js) - Google Analytics