注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

liu的博客

 
 
 

日志

 
 

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

2009-12-04 11:49:49|  分类: jsp |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

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 < rCnt; rowIndex++) {
                if (!matrix[rowIndex]) {
                    matrix[rowIndex] = [];
                }
                for (var cellIndex = 0, cCnt = table.rows[rowIndex].cells.length; cellIndex < 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 < cell.rowSpan; i++) {
                        if (!matrix[rowIndex + i]) {
                            matrix[rowIndex + i] = [];
                        }
                        for (var j = 0; j < 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 < rCnt; rowIndex++) {
                for (columnIndex = 0,cCnt = matrix[0].length; columnIndex < cCnt; columnIndex++) {
                    if ($(matrix[rowIndex][columnIndex]).hasClass('selected')) {
                        if (rowIndex > maxRowIndex) {
                            maxRowIndex = rowIndex;
                        }
                        if (rowIndex < minRowIndex) {
                            minRowIndex = rowIndex;
                        }
                        if (columnIndex > maxColumnIndex) {
                            maxColumnIndex = columnIndex;
                        }
                        if (columnIndex < minColumnIndex) {
                            minColumnIndex = columnIndex;
                        }
                    }
                }
            }

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

            if (mergable) {
                //then merge
                var cellToMergeInto = matrix[minRowIndex][minColumnIndex];
                for (rowIndex = minRowIndex; rowIndex <= maxRowIndex; rowIndex++) {
                    for (columnIndex = minColumnIndex; columnIndex <= maxColumnIndex; columnIndex++) {
                        var cell = matrix[rowIndex][columnIndex];
                        if (cell !== cellToMergeInto) {
                            for (var i = 0; i < cell.rowSpan; i++) {
                                for (var j = 0; j < 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 && (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('');
            });

            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('');
                    };
                }
                else {
                    var jRow = $(table.rows[rowIndex + time]);
                    task = function () {
                        jRow.prepend('');
                    };
                }

                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 , rCnt, cCnt;

            cCnt = matrix[0].length;
            //clean up empty rows
            for (rowIndex = 0,rCnt = matrix.length; rowIndex < rCnt; rowIndex++) {
                var isEmptyRow = true;
                for (columnIndex = 0; columnIndex < 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 < 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 < 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 < cCnt; columnIndex++) {
                var isEmptyColumn = true;
                for (rowIndex = 0; rowIndex < 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 < rCnt);

   //remove empty column from matrix
                for (rowIndex = 0; rowIndex < rCnt; rowIndex++) {
                    for (var j = columnIndex, jLen = cCnt - 1; j < 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 && 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 && j < firstApperanceColumnIndex + cell.colSpan; j++) {
                    for (i = 0,iLen = matrix.length; i < iLen; i++) {
                        if (matrix[i][j].colSpan !== 1) {
                            continue;
                        }

                        jCell = $(matrix[i][j]);
                        offset = jCell.offset();
                        if (offset.left <= pageX && offset.left + jCell.width() >= 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 && i < cell.parentNode.rowIndex + cell.rowSpan; i++) {
                    for (j = 0; j < jLen; j++) {
                        if (matrix[i][j].rowSpan !== 1) {
                            continue;
                        }

                        jCell = $(matrix[i][j]);
                        offset = jCell.offset();
                        if (offset.top <= pageY && offset.top + jCell.height() >= 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) > 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 < rCnt; rowIndex++) {
                for (var columnIndex = 0; columnIndex < 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 < matrix[0].length - 1) {
                for (var rowIndex = 0, rCnt = matrix.length; rowIndex < rCnt; rowIndex++) {
                    var currentCell = matrix[rowIndex][columnIndex];

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

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

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

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

            $('col:eq(' + columnIndex + ')', table).after('');
        },
        /**
         * 在单元格所在列左边插入新列
         * @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 > 0) {
                for (var rowIndex = 0, rCnt = matrix.length; rowIndex < rCnt; rowIndex++) {
                    var currentCell = matrix[rowIndex][columnIndex];

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

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

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

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

            $('col:eq(' + columnIndex + ')', table).before('');
        },
        /**
         * 在单元格所在行下面插入新行
         * @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 = '';

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

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

            newRow += '';

            $(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 = '';

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

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

            newRow += '';

            $(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 < cCnt; columnIndex++) {
                var currentCell = matrix[rowIndex][columnIndex];
                if (currentCell.rowSpan > 1) {
                    currentCell.rowSpan -= 1;

                    if (currentCell.parentNode.rowIndex === rowIndex) {
                        var cellToInsertAfter = null;
                        for (var columnIndexOfTheRowBelow = columnIndex - 1; columnIndexOfTheRowBelow >= 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 < rCnt; rowIndex++) {
                var currentCell = matrix[rowIndex][columnIndex];
                if (currentCell.colSpan > 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));
        }
    };
})();

  评论这张
 
阅读(2130)| 评论(1)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017