搜索

有思俱乐部学习园地

U.UF.E.Table() 创建表格。


函数源码:

/**
 *  表格总接口
 * range为编辑器的光标对象
 */
U.UF.E.Table = function (range) {
    var _table = U.UF.E.Table;  //简写命名空间
    _table._range = range;
    var _alertTemplate = "<p style='text-align: left;margin-left: 60px;'>请输入行: <input type='number' style='width: 40px;' min='1' id='U_UF_E_Table_row'></p>" +
            "<p style='text-align: left;margin-left: 60px;'>请输入列: <input type='number' min='1' style='width: 40px;' id='U_UF_E_Table_col'></p>";    //弹出框的html代码
    U.UF.UI.confirm(_alertTemplate, function () {    //弹框输入 行 和 列
        var _row = $("#U_UF_E_Table_row")[0].value;   //行
        var _col = $("#U_UF_E_Table_col")[0].value;   //列
        if (_row >= 1 && _col >= 1) {   //如果 行和列的值大于1 则添加表格
            _table.addTable(_row, _col);
        }
    });
    $(document).unbind('mousedown', U.UF.E.Table.removeFocus); //先取消事件监听 在添加 防止重复绑定
    $(document).bind('mousedown', U.UF.E.Table.removeFocus); //添加点击时的聚焦效果 并且若存在textarea元素 则删除并获取textarea的值给td
};

/**
* 创建表格
* @param row   表格的行
* @param col   表格的列
*/
U.UF.E.Table.addTable = function (row, col) {
    var _table = U.UF.E.Table;  //简写命名空间
    var _pelDiv = _table.createTablePel();  //table父节点
    var _tableEl = $$("table", { style: { cssText: "border-spacing: 0;border-collapse: collapse;width: 100%;position: relative;table-layout:fixed;"} }, _pelDiv);   //创建table
    _table.tableOver(_tableEl);  //添加选中选出事件 防止选中td时 选中外面的元素 而报错
    var _tbodyEl = $$("tbody", {}, _tableEl);
    var _tdWidth = Math.floor(_tableEl.clientWidth / col); //给每个td添加width = table宽/col(列)
    for (var i = 0; i < row; i++) { //循环创建tr td
        var _trEl = $$("tr", { style: { position: "relative", height: "30px"} }, _tbodyEl);  //创建tr 默认高 30px
        for (var j = 0; j < col; j++) {
            var _tdEl = $$("td", { style: { width: _tdWidth + "px", cssText: "border: 2px solid #8b7d7d;padding: 0;box-sizing:border-box;"} }, _trEl);
            var _colRule = $$("div", { style: { position: "absolute", top: 0, "margin-left": _tdWidth + "px", cursor: "col-resize", height: "100%", width: "7px" }, className: "U_UF_E_Table_colRule" }, _tdEl); //列尺
            _table.colExpanding(_colRule); //给列尺 添加左右拉伸事件
            _table.tdDbClick(_tdEl); //添加双击事件
            _table.dragCheckd(_tdEl);    //td拖拽的选中事件
        }
        var _rowRule = $$("div", { style: { position: "absolute", zIndex: "1", left: 0, "margin-top": "30px", cursor: "row-resize", height: "3px", width: "100%" }, className: "U_UF_E_Table_rowRule" }, _trEl); //行尺
        _table.rowExpanding(_rowRule); //给行尺 上下拉伸事件
    }
    _table.firstLinePeak(_tableEl);    //第一行tr的所有列尺添加zIndex为1
    _table.rightClick(_tableEl);    //添加右键

};


/**
* 换行并返回该行的div 然后在该行下面创建空div(防止表格后无法聚焦)  
* return 创建表格的div(父节点)
* 调用的地方:U.UF.E.Table.addTable(创建表格)
*/
U.UF.E.Table.createTablePel = function () {
    var _table = U.UF.E.Table;
    console.log(_table._range);
    var _range = U.UF.E.Table._range,   //获取光标
            _div = U.UF.E.getLineElement(_range.startContainer);    //获取光标所在行的div
    if (_div.textContent !== "") {   //如果该行有内容 则新建一行div
        var _div = $("#" + U.UF.E.key.addLine(_range))[0];
        if (_div.textContent !== "") {
            U.UF.E.key.addLine(_range);
        }
    }
    $(_div).attr("contenteditable", "false");    //无内容的div(表格的父节点) 取消编辑效果
    _div.style.cssText = "overflow-y:hidden;padding-bottom:5px;padding-right:7px;width:90%";   //_div的样式
    U.UF.E.key.addLine(_range);   //在表格的父节点下添加div 防止无法聚焦
    _table.placeCaretAtEnd(_div);
    return _div;
};

/**
* 将表格的第一个tr里的所有列尺元素 添加 zindex为1 的样式
* tableEl 表格元素
*/
U.UF.E.Table.firstLinePeak = function (tableEl) {
    $(tableEl).find(".peak").removeClass("U_UF_E_Table_peak");  //删除所有列尺的zIndex为1的样式
    var _colRuleList = tableEl.querySelectorAll("tr")[0].querySelectorAll(".U_UF_E_Table_colRule"); //获取第一行的列尺
    for (var i = 0, len = _colRuleList.length; i < len; i++) {
        var _colRule = _colRuleList[i];
        $(_colRule).addClass("U_UF_E_Table_peak");
    }
};

/**
* @param table 防止选中事件时选中到表格外的元素而报错
* 调用的地方:U.UF.E.Table.addTable
*/
U.UF.E.Table.tableOver = function (table) {
    $(table).bind('mouseover', function () {    //判断鼠标是否在该table里 如果在 才可以选择区域
        this.over = true;
    });
    $(table).bind('mouseout', function () {
        this.over = false;
    });
};


/**
* @param colrule 列尺(div) 添加左右拉伸事件
* 调用的地方:U.UF.E.Table.addTable(添加表格)  U.UF.E.Table.insertTd(插入列)  U.UF.E.Table.cloneTr(添加行)  
*/
U.UF.E.Table.colExpanding = function (colrule) {
    var _div = colrule;
    $(_div).bind({
        'mousedown': function (e) {
            $("#U_UF_EL_rightmenu")[0] && $("#U_UF_EL_rightmenu")[0].remove();    //删除右键元素
            U.UF.EV.stopBubble(e);                                    //阻止冒泡
            this.style.backgroundColor = "#8cb3e0"; //修改列尺(div)的颜色
            var _table = U.UF.E.Table;
            var _this = this;
            var _tdEl = this.parentNode;  //获取td(每个列对应一个td父节点)
            var _tableEl = _table.parentSelect(this, "table");    //获取所在的table
            var _tableElWidth = _tableEl.clientWidth;       //table当前的宽度
            var _trList = _tableEl.querySelectorAll("tr");    //获取所有的tr
            var _tdElIndex = _table.index(_tdEl);  //获取td在tr的索引位置(列)
            var _dis,   //移动的距离
                    _disX;   //移动后的位置
            var _oMouseX = e.pageX;                                   //获取鼠标按下时的X坐标
            var _oX = parseInt(this.style.marginLeft);               //获取当前Left坐标
            var expandingMove = function (e) {                      //拖拽时移动用的函数
                U.UF.EV.stopDefault(e);                               //取消默认拖拽
                var _mouseX = e.pageX;                                //鼠标移动时的x坐标
                _dis = _mouseX - _oMouseX;                            //移动的距离
                _disX = _dis + _oX;                                   //移动后的位置
                _disX = Math.max(50, _disX);                          //拉伸后的td的宽度不能小于50px
                $(_this).css("margin-left", _disX + "px");             //同步当前的left
            };
            var expandingUp = function () {                  //拖拽时松开用的函数
                _this.style.backgroundColor = "";   //列尺颜色 变为空
                for (var i = 0, len = _trList.length; i < len; i++) {
                    var _colTdEl = _trList[i].querySelectorAll("td")[_tdElIndex];   //列的td
                    _colTdEl.style.width = _disX + "px";    //同步宽度
                    var _colRule = _colTdEl.querySelectorAll('.U_UF_E_Table_colRule');    //该td对应的列尺
                    $(_colRule).css("margin-left", _disX + "px"); //同步当前的left
                }
                _tableEl.style.width = _tableElWidth + _dis + "px";  //表格的宽度 跟随增缩

                $(document).unbind('mousemove', expandingMove);
                $(document).unbind('mouseup', expandingUp);
            };

            $(document).bind('mousemove', expandingMove);
            $(document).bind('mouseup', expandingUp)

        },
        'dblclick': function (e) {
            U.UF.EV.stopBubble(e);                                    //阻止冒泡
        },   //阻止td的双击
        'mousemove': function (e) {
            U.UF.EV.stopBubble(e);                                    //阻止冒泡
            U.UF.EV.stopDefault(e);                                //取消默认拖拽
        }
    });
};


/**
* 调用的地方:U.UF.E.Table.addTable(添加表格) U.UF.E.Table.cloneTr(添加行)  
* @param rowrule 行尺(div) 添加上下拉伸事件
*/
U.UF.E.Table.rowExpanding = function (rowrule) {   //高度扩张
    var _div = rowrule;
    $(_div).bind({
        'mousedown': function (e) {
            $("#U_UF_EL_rightmenu")[0] && $("#U_UF_EL_rightmenu")[0].remove();    //删除右键元素
            this.style.backgroundColor = "#8cb3e0";
            U.UF.EV.stopBubble(e);                                     //阻止冒泡
            var _oMouseY = e.pageY;                                    //获取鼠标按下时的Y坐标
            var _this = this;
            var _oY = parseInt(this.style.marginTop);                 //获取当前Top坐标
            var _trEl = this.parentNode;                                //获取tr
            var expandingMove = function (e) {                           //拖拽时移动用的函数
                U.UF.EV.stopDefault(e);                                //取消默认拖拽
                var _mouseY = e.pageY;                                 //鼠标移动时的Y坐标
                var _dis = _mouseY - _oMouseY + _oY;                   //移动的距离
                _dis = Math.max(30, _dis);                              //拉伸后的tr的高度不能小于30px
                _trEl.style.height = _dis + "px";
                var clienHeight = _trEl.clientHeight; //tr的高度 会根据内容有个最小值 因此 这个tr最后的高度 才是最终值
                _dis = Math.max(clienHeight, _dis);
                _trEl.style.height = _dis + "px";
                $(_this).css("margin-top", _dis + "px");
            };
            var expandingUp = function () {                  //拖拽时松开用的函数
                _this.style.backgroundColor = "";
                $(document).unbind('mousemove', expandingMove);
                $(document).unbind('mouseup', expandingUp);
            };

            $(document).bind('mousemove', expandingMove);
            $(document).bind('mouseup', expandingUp)
        },
        'mousemove': function (e) {
            U.UF.EV.stopBubble(e);                                    //阻止冒泡
            U.UF.EV.stopDefault(e);                                //取消默认拖拽
        }
    });
};
/**
*  双击td添加文本框
* @param td 添加双击事件的td元素
* 调用的地方:U.UF.E.Table.addTable(添加表格)  U.UF.E.Table.insertTd(插入列)  U.UF.E.Table.cloneTr(添加行)  
*/
U.UF.E.Table.tdDbClick = function (td) {
    $(td).bind('dblclick', function () {
        var _table = U.UF.E.Table;  //简写命名空间
        var _textNode = _table.getFirstText(this), //获取td的第一个文本节点
                _text = null;
        if (_textNode) {  //如果拥有文本节点 则获取他的文本内容 并删除该文本节点
            _text = _textNode.nodeValue;
            _textNode.remove();
        }
        var _textArea = $$("textarea", { className: "U_UF_E_Table_tdText", value: _text }, this);   //添加textarea 并且将td的内容放入textarea
        $(_textArea).bind('mousedown', function (e) {
            $("#U_UF_EL_rightmenu")[0] && $("#U_UF_EL_rightmenu")[0].remove();    //删除右键元素
            U.UF.EV.stopBubble(e);                                    //阻止冒泡
        }); //阻止td的冒泡 (选中效果 和 聚焦效果)
        $(_textArea).bind('dblclick', function (e) {
            U.UF.EV.stopBubble(e);                                    //阻止冒泡
        }); //阻止td的冒泡(双击添加textarea效果)
        var autoHeight = function (el) {  //表格自动适应高
            el.nodeType === 1 ? "" : el = el.target;    //el只能为textarea
            el.style.height = 'auto';
            el.style.height = el.scrollHeight + "px";   //此处为textarea的高度跟随文字输入的内容自动增高
            var _rowRuleList = $(".U_UF_E_Table_rowRule");   //获取所有行尺
            for (var i = 0, len = _rowRuleList.length; i < len; i++) {
                var _trPel = _rowRuleList[i].parentNode;    //每个行尺 对应一个 tr元素
                _trPel.style.height = _trPel.clientHeight;  //使每个tr的height 等于 clientHeight
                $(_rowRuleList[i]).css("margin-top", _trPel.clientHeight + "px");    //同步margintop 的位置
            }
        };
        autoHeight(_textArea);  //由于textarea输入自后td的高度会变化 因此所有行尺的位置重新定位
        $(_textArea).bind('keydown', autoHeight);    //键盘监听 自动适应高
        $(_textArea).bind('keyup', autoHeight);  //键盘监听 自动适应高
        $(_textArea).bind('mousemove', function (e) {
            U.UF.EV.stopBubble(e);                                    //阻止冒泡
        });  //由于td的选中效果已阻止默认拖拽事件 因此给textarea加个阻止冒泡效果
        _textArea.focus();  //给textarea聚焦
    });
};
/**
* 给td添加鼠标拖拽的选中效果
* @param td 添加鼠标拖拽效果的 td
* 调用的地方:U.UF.E.Table.addTable(添加表格)  U.UF.E.Table.insertTd(插入列)  U.UF.E.Table.cloneTr(添加行)  
*/
U.UF.E.Table.dragCheckd = function (td) {
    var _tdEl = td;
    $(_tdEl).bind('mousedown', function (e) {
        $("#U_UF_EL_rightmenu")[0] && $("#U_UF_EL_rightmenu")[0].remove();    //删除右键元素
        U.UF.EV.stopBubble(e);                                    //阻止冒泡
        if (e.button === 2) return;
        var _table = U.UF.E.Table;
        _table.removeFocus();   //删除掉所有聚焦和选中的元素
        $(this).addClass("U_UF_E_Table_tdCurrent");      //给td添加聚焦样式
        var _start = this;          //获取点击元素
        var _startX = _table.index(_start); //记录x坐标轴
        var _startY = _table.index(this.parentNode);   //获取y坐标轴
        var _checkFlag = true;   //注意下面的_table.over是一个属性 防止选中区域在表格外面
        var _tableEl = _table.parentSelect(this, "table");    //获取父节点table
        //$(".U_UF_E_Table_tdCheckd").removeClass("U_UF_E_Table_tdCheckd");
        var _drapMove = function (e) {                      //拖拽时移动用的函数
            var tagEl = e.target;
            U.UF.EV.stopBubble(e);                                    //阻止冒泡
            U.UF.EV.stopDefault(e);                                //取消默认拖拽
            if (!(_tableEl.over) || (tagEl === _start && _checkFlag)) return;    //此处防止选中table外元素 与 鼠标必须选中两个td才会有选中效果
            _checkFlag = false;  //如果不同 则选中过两个元素
            var _endX = _table.index(tagEl);   //结束点的x坐标
            var _endY = _table.index(tagEl.parentNode); //结束点的y坐标
            $(".U_UF_E_Table_tdCheckd").removeClass("U_UF_E_Table_tdCheckd");
            _table.tdAddClass(tagEl.parentNode, _startX, _startY, _endX, _endY);   //给开始点和结束点组成的矩形 添加选中的class
        };
        var _dragUp = function () {                  //拖拽时松开用的函数
            $(document).unbind('mousemove', _drapMove);
            $(document).unbind('mouseup', _dragUp);
            _checkFlag = true;
        };
        $(document).bind('mousemove', _drapMove);
        $(document).bind('mouseup', _dragUp);
    });
};

/**
*
* @param tr 获取所有tr用的(遍历所有tr)
* @param x1 开始点x坐标
* @param y1 开始点y坐标
* @param x2 结束点x坐标
* @param y2 结束点y坐标
* 调用的地方:U.UF.E.Table.dragCheckd(td拖拽选中事件) 
*/
U.UF.E.Table.tdAddClass = function (tr, x1, y1, x2, y2) {   //获取首尾坐标轴 最后组成矩形 然后添加选中的class
    var _trList = tr.parentNode.querySelectorAll("tr");
    var _x1 = Math.min(x1, x2);
    var _x2 = Math.max(x1, x2);
    var _y1 = Math.min(y1, y2);
    var _y2 = Math.max(y1, y2);
    for (var i = _y1; i <= _y2; i++) {
        var _tdList = _trList[i].querySelectorAll("td");
        for (var j = _x1; j <= _x2; j++) {
            $(_tdList[j]).addClass("U_UF_E_Table_tdCheckd");
        }
    }
}
/**
* 左右侧添加列
* @param direction 参数为 "left" 或 "right"
* 调用的地方:U.UF.E.Table.rightClick(右键菜单)
*/
U.UF.E.Table.addColumn = function (direction) {
    var _table = U.UF.E.Table;
    var tdList = $(".U_UF_E_Table_tdCheckd");
    if (!tdList[0]) { //如果没有 选中的td
        if ($(".U_UF_E_Table_tdCurrent")[0]) { //再判断 有无聚焦的 td
            tdList = $(".U_UF_E_Table_tdCurrent");
        } else {
            return; //如果没有 则直接返回
        }
    }
    var _tdEl;
    if (direction === "left") {
        _tdEl = tdList[0];
    } else if (direction === "right") {
        _tdEl = tdList[tdList.length - 1];
    }
    _table.insertTd(_tdEl, direction);
};

/**
* 向每个tr的列(td) 前方或后方插入td
* @param td  td元素
* @param direction  供添加左右列用的api 参数为 "left" 或 "right"
* 调用的地方:U.UF.E.Table.addColumn(添加列)
*/
U.UF.E.Table.insertTd = function (td, direction) {
    var _table = U.UF.E.Table;
    var _tdEl = td,
            _index = _table.index(_tdEl),    //在tr中位于所有td的位置
            _dir = direction;
    var _tableEl = _table.parentSelect(_tdEl, 'table');
    var _trList = $(_tableEl).find("tr");
    var _tableElWidth = _tableEl.offsetWidth; //记住当前的宽度

    for (var i = 0, len = _trList.length; i < len; i++) {  //遍历每个tr的列(td) 在前方或后方插入td
        var _currentColumn = $(_trList[i]).find("td")[_index];    //当前列
        var _tdElClone = _tdEl.cloneNode(); //克隆td
        if (_dir === "left") {
            _table.Before(_currentColumn, _tdElClone);    //在列的前面添加td
        } else if (_dir === "right") {
            _table.After(_currentColumn, _tdElClone); //在列的后面添加td
        }
        var _colRule = $$("div", { style: { position: "absolute", top: 0, "margin-left": _tdElClone.style.width, cursor: "col-resize", height: "100%", width: "7px" }, className: "U_UF_E_Table_colRule" }, _tdElClone); //列尺
        _table.colExpanding(_colRule); //添加左右拉伸事件
        _table.tdDbClick(_tdElClone); //添加双击事件
        _table.dragCheckd(_tdElClone);    //td拖拽的选中事件
        $(_tdElClone).removeClass("U_UF_E_Table_tdCheckd"); //清楚添加后的列的选中的样式
        $(_tdElClone).removeClass("U_UF_E_Table_tdCurrent");
    }
    _tableEl.style.width = _tableElWidth + _tdEl.offsetWidth + "px";
    _table.firstLinePeak(_tableEl);    //第一行tr的所有列尺添加zIndex为1
};
/**
* 上下添加行
* @param direction 参数为 "up" 或 "down"
* 调用的地方:U.UF.E.Table.rightClick(右键菜单)
*/
U.UF.E.Table.addTr = function (direction) {
    var _table = U.UF.E.Table;
    var tdList = $(".U_UF_E_Table_tdCheckd");
    if (!tdList[0]) { //如果没有 选中的td
        if ($(".U_UF_E_Table_tdCurrent")[0]) { //再判断 有无聚焦的 td
            tdList = $(".U_UF_E_Table_tdCurrent");
        } else {
            return; //如果没有 则直接返回
        }
    }
    var _trEl, _trElClone;
    if (direction === "up") {
        _trEl = tdList[0].parentNode;
        _trElClone = _table.cloneTr(_trEl); //克隆tr 并给td 添加表格事件
        _table.Before(_trEl, _trElClone);
    } else if (direction === "down") {
        _trEl = tdList[tdList.length - 1].parentNode;    //向下插入行
        _trElClone = _table.cloneTr(_trEl); //克隆tr 并给td 添加表格事件
        _table.After(_trEl, _trElClone);
    }
    var _tableEl = _table.parentSelect(tdList[0], 'table');
    _table.firstLinePeak(_tableEl);    //将表格的第一个tr里的所有列尺元素 添加 zindex为1 的样式
};

/**
* 克隆tr 并添加表格事件
* @param tr 需要克隆的tr
* 调用的地方:U.UF.E.Table.addTr(添加行)
*/
U.UF.E.Table.cloneTr = function (tr) {
    var _table = U.UF.E.Table;
    var _trNodes = tr.cloneNode(true); //带子节点的tr
    var _trClone = tr.cloneNode();  //无子节点的tr
    var _cloneTd = $(_trNodes).find("td");
    for (var i = 0, len = _cloneTd.length; i < len; i++) {
        var _td = _cloneTd[i].cloneNode();
        $(_td).rmAttr("rowspan");   //删除跨行的属性
        _trClone.appendChild(_td);
        var _colRule = $$("div", { style: { position: "absolute", top: 0, "margin-left": _td.style.width, cursor: "col-resize", height: "100%", width: "7px" }, className: "U_UF_E_Table_colRule" }, _td); //列尺
        _table.colExpanding(_colRule); //添加左右拉伸事件
        _table.tdDbClick(_td); //添加双击事件
        _table.dragCheckd(_td);    //td拖拽的选中事件
    }
    var _rowRule = $$("div", { style: { position: "absolute", zIndex: "1", left: 0, "margin-top": "30px", cursor: "row-resize", height: "3px", width: "100%" }, className: "U_UF_E_Table_rowRule" }, _trClone); //行尺
    _table.rowExpanding(_rowRule);  //上下拉伸事件
    $(_trClone).find(".U_UF_E_Table_tdCheckd").removeClass("U_UF_E_Table_tdCheckd");    //删除所有选中表格和 聚焦表格的样式
    $(_trClone).find(".U_UF_E_Table_tdCurrent").removeClass("U_UF_E_Table_tdCurrent");
    return _trClone;
};
/**
*  合并单元格功能
* 调用的地方:U.UF.E.Table.rightClick(右键菜单)
*/
U.UF.E.Table.mergeCells = function () {
    var _table = U.UF.E.Table;
    var _tdList = $(".U_UF_E_Table_tdCheckd");
    if (_tdList.length <= 1) return;
    var _x1 = _table.index(_tdList[0]);  //x坐标开始点
    var _y1 = _table.index(_tdList[0].parentNode); //y坐标开始点
    var _x2 = _table.index(_tdList[_tdList.length - 1]); //x坐标结束点
    var _y2 = _table.index(_tdList[_tdList.length - 1].parentNode);  //y坐标结束点
    var _tableEl = _table.parentSelect(_tdList[0], "table");    //获取table元素
    var _trList = _tableEl.querySelectorAll("tr");  //获取table里所有tr
    var _text = "";     //合并后的总内容
    var allWidth = 0;   //合并后的总宽度
    for (var i = _y1; i <= _y2; i++) {  /*该循环*/
        var _trAllTd = _trList[i].querySelectorAll("td"); //获取选中表格的所在tr
        for (var j = _x1; j <= _x2; j++) { // 获取选中表格的 所在td
            var _tdEl = _trAllTd[j];    //获取每个选中的单元格
            _text += _tdEl.innerText;   //合并内容
            if (i === _y1) { //只计算选中表格第一行 的总宽度
                allWidth += _tdEl.offsetWidth;
            }
            if (i === _y1 && j === _x1) continue;    //第一个td就跳过 其他的则display为 none
            $(_tdEl).css("display", "none");
        }
    }

    var _textNode = document.createTextNode(_text); //文字节点 _text为总内容
    var _firstNode = _table.getFirstText(_tdList[0]);   //获取被合并单元格的td所在的文字节点
    _firstNode ? _firstNode.remove() : ""; //如果存在文字节点 则删除
    _tdList[0].appendChild(_textNode); //然后将新创建的总文字节点 添加到该单元格里
    _tdList[0].style.width = allWidth + "px"; //添加总宽度
    var _col = $(_tdList[0]).attr("colspan");
    _col <= _x2 - _x1 + 1 ? $(_tdList[0]).attr("colspan", _x2 - _x1 + 1) : ""; //跨的列数
    $(_tdList[0]).attr("rowspan", _y2 - _y1 + 1); //跨的行数
    $(_tdList[0].querySelector(".tdColumns")).css("margin-left", allWidth + 'px');   //更新 列尺的位置
    _table.firstLinePeak(_tableEl);    //将表格的第一个tr里的所有列尺元素 添加 zindex为1 的样式
};
/**
*  删除行
* 调用的地方:U.UF.E.Table.rightClick(右键菜单)
*/
U.UF.E.Table.removeTr = function () {
    var _table = U.UF.E.Table;
    var tdList = $(".U_UF_E_Table_tdCheckd");
    if (!tdList[0]) { //如果没有 选中的td
        if ($(".U_UF_E_Table_tdCurrent")[0]) { //再判断 有无聚焦的 td
            tdList = $(".U_UF_E_Table_tdCurrent");
        } else {
            return; //如果没有 则直接返回
        }
    }
    var start = _table.index(tdList[0].parentNode);
    var end = _table.index(tdList[tdList.length - 1].parentNode);
    var _tableEl = _table.parentSelect(tdList[0], "table");
    var _parentDiv = _table.parentSelect(_tableEl, "div");
    var _trList = $(_tableEl).find("tr");
    for (var i = start; i <= end; i++) {
        _trList[i].remove();
    }
    if (!(_tableEl.querySelectorAll("tr").length)) {
        _parentDiv.remove();
        return
    }
    _table.firstLinePeak(_tableEl);    //将表格的第一个tr里的所有列尺元素 添加 zindex为1 的样式
};

/**
* 删除列
* 调用的地方:U.UF.E.Table.rightClick(右键菜单)
*/
U.UF.E.Table.removeColumn = function () {
    var _table = U.UF.E.Table
    var tdList = $(".U_UF_E_Table_tdCheckd");
    if (!tdList[0]) { //如果没有 选中的td
        if ($(".U_UF_E_Table_tdCurrent")[0]) { //再判断 有无聚焦的 td
            tdList = $(".U_UF_E_Table_tdCurrent");
        } else {
            return; //如果没有 则直接返回
        }
    }
    var _start = _table.index(tdList[0]);  //列的开始位置
    var _end = _table.index(tdList[tdList.length - 1]); //列的结束位置

    var _tableEl = _table.parentSelect(tdList[0], 'table');
    var _trList = $(_tableEl).find("tr");
    var _widthSum = 0;  //删除列的总宽
    for (var i = 0, len = _trList.length; i < len; i++) {
        var _tdList = $(_trList[i]).find("td");
        for (var j = _start; j <= _end; j++) {
            i === 0 ? _widthSum += _tdList[j].offsetWidth : "";    //只计算第一行删除的列宽
            _tdList[j].remove();
        }
    }
    _tableEl.style.width = _tableEl.offsetWidth - _widthSum + "px";
    var _tdLen = _tableEl.querySelectorAll("td").length;  //获取当前列的长度
    if (!_tdLen) {    //如果table不存在td 则删除table和 table父节点(div)
        var _parentDiv = _table.parentSelect(_tableEl, "div");
        _parentDiv.remove();
        return
    }
    _table.firstLinePeak(_tableEl);    //将表格的第一个tr里的所有列尺元素 添加 zindex为1 的样式
};
/**
*
*  tableEl 表格元素 添加右键
*  调用的地方:U.UF.E.Table.addTable(添加表格)
*/
U.UF.E.Table.rightClick = function (tableEl) {
    var _table = U.UF.E.Table;
    var leftAddCol = {
        innerHTML: '左侧添加列',
        onclick: function () {
            _table.addColumn("left");
            $("#U_UF_EL_rightmenu")[0] && $("#U_UF_EL_rightmenu")[0].remove();    //删除右键元素
        },
        onmousedown: function (e) {
            U.UF.EV.stopBubble(e);                                    //阻止冒泡
        }
    };
    var rightAddCol = {
        innerHTML: '右侧添加列',
        onclick: function () {
            _table.addColumn("right");
            $("#U_UF_EL_rightmenu")[0] && $("#U_UF_EL_rightmenu")[0].remove();    //删除右键元素
        },
        onmousedown: function (e) {
            U.UF.EV.stopBubble(e);                                    //阻止冒泡
        }
    };
    var upAddLine = {
        innerHTML: '向上添加行',
        onclick: function () {
            _table.addTr("up");
            $("#U_UF_EL_rightmenu")[0] && $("#U_UF_EL_rightmenu")[0].remove();    //删除右键元素
        },
        onmousedown: function (e) {
            U.UF.EV.stopBubble(e);                                    //阻止冒泡
        }
    };
    var downAddLine = {
        innerHTML: '向下添加行',
        onclick: function () {
            _table.addTr("down");
            $("#U_UF_EL_rightmenu")[0] && $("#U_UF_EL_rightmenu")[0].remove();    //删除右键元素
        },
        onmousedown: function (e) {
            U.UF.EV.stopBubble(e);                                    //阻止冒泡
        }
    };
    var removeCol = {
        innerHTML: '删除列',
        onclick: function () {
            _table.removeColumn();
            $("#U_UF_EL_rightmenu")[0] && $("#U_UF_EL_rightmenu")[0].remove();    //删除右键元素
        },
        onmousedown: function (e) {
            U.UF.EV.stopBubble(e);                                    //阻止冒泡
        }
    };
    var removeLine = {
        innerHTML: '删除行',
        onclick: function () {
            _table.removeTr();
            $("#U_UF_EL_rightmenu")[0] && $("#U_UF_EL_rightmenu")[0].remove();    //删除右键元素
        },
        onmousedown: function (e) {
            U.UF.EV.stopBubble(e);                                    //阻止冒泡
        }
    };
    var mergeCells = {
        innerHTML: '合并单元格',
        onclick: function () {
            _table.mergeCells();
            $("#U_UF_EL_rightmenu")[0] && $("#U_UF_EL_rightmenu")[0].remove();    //删除右键元素
        },
        onmousedown: function (e) {
            U.UF.EV.stopBubble(e);                                    //阻止冒泡
        }
    };
    var _arr = [leftAddCol, rightAddCol, upAddLine, downAddLine, removeCol, removeLine, mergeCells];
    $(tableEl).bind('contextmenu', function (e) {
        U.UF.EV.stopBubble(e);                                    //阻止冒泡
        U.UF.EV.stopDefault();
        U.UF.EL.rightMenu(_arr, tableEl);
        $("#U_UF_EL_rightmenu").bind('contextmenu', function (e) {   //右键元素属于table 因此需要阻止冒泡
            U.UF.EV.stopBubble(e);                                    //阻止冒泡
        });
    });
    $(tableEl).bind('mousedown', function (e) {
        $("#U_UF_EL_rightmenu")[0] && $("#U_UF_EL_rightmenu")[0].remove();    //删除右键元素
    });
};
/**
* 添加点击时的聚焦效果 并且若存在textarea元素 则删除并获取textarea的值给td
* 调用的地方:U.UF.E.Table.addTable(添加表格) U.UF.E.Table.dragCheckd(td添加鼠标拖拽)
*/ 
U.UF.E.Table.removeFocus = function () {        //添加点击时的聚焦效果 并且若存在textarea元素 则删除并获取textarea的值给td
    $(".U_UF_E_Table_tdCheckd").removeClass("U_UF_E_Table_tdCheckd");
    $(".U_UF_E_Table_tdCurrent").removeClass("U_UF_E_Table_tdCurrent");
    var _textArea = $(".U_UF_E_Table_tdText")[0],        //如果存在textarea元素 则将其变为文本
            _pel;
    _textArea ? _pel = _textArea.parentNode : ""; //如果textArea存在 先获取父节点td 然后将其变为文本
    if (_pel) {
        var _textNode = document.createTextNode(_textArea.value);
        _pel.appendChild(_textNode);
        _textArea.remove();
    }
    var _rowRuleList = $(".U_UF_E_Table_rowRule"); //使div的margintop 及时更新
    for (var i = 0, len = _rowRuleList.length; i < len; i++) {
        var _trEl = _rowRuleList[i].parentNode;
        _trEl.style.height = _trEl.clientHeight;
        $(_rowRuleList[i]).css("margin-top", _trEl.clientHeight + "px");
    }
};

附带的api:

/**
* 将表格的第一个tr里的所有列尺元素 添加 zindex为1 的样式
* tableEl 表格元素
*/
U.UF.E.Table.firstLinePeak = function (tableEl) {
    $(tableEl).find(".peak").removeClass("U_UF_E_Table_peak");  //删除所有列尺的zIndex为1的样式
    var _colRuleList = tableEl.querySelectorAll("tr")[0].querySelectorAll(".U_UF_E_Table_colRule"); //获取第一行的列尺
    for (var i = 0, len = _colRuleList.length; i < len; i++) {
        var _colRule = _colRuleList[i];
        $(_colRule).addClass("U_UF_E_Table_peak");
    }
};

/**
*
* @param el 元素
* @returns {number} 返回当前元素在所有同类型元素 的第几个位置
*/
U.UF.E.Table.index = function (el) {
    var _el = el;
    var _name = _el.nodeName;   //获取该元素的节点名
    var _list = _el.parentNode.querySelectorAll(_name); //获取父节下的所有自己的节点
    for (var i = 0, len = _list.length; i < len; i++) {
        if (_list[i] === _el) {
            return i;   //返回在数组的索引
        }
    }
};

/**
* 获取td的第一个文本元素
*/
U.UF.E.Table.getFirstText = function (td) {
    var _child = td.childNodes;
    for (var i = 0, len = _child.length; i < len; i++) {
        if (_child[i].nodeType === 3) {
            return _child[i];
        }
    }
    return false;
}

/*获取指定标签的父节点*/
U.UF.E.Table.parentSelect = function (el, type) {
    var _this = el;
    var type = type.toUpperCase();
    if (_this.tagName === type) return _this;
    var parent = _this.parentNode;
    while (parent.tagName !== type) {
        parent = parent.parentNode;
    }
    return parent;
};

/*在元素前面插入新元素*/
U.UF.E.Table.Before = function (el, newEl) {
    var _this = el;
    var parentEl = _this.parentNode;
    parentEl.insertBefore(newEl, _this);
};

/*在元素后面插入新元素*/
U.UF.E.Table.After = function (el, newEl) {
    var _this = el;
    var parentEl = _this.parentNode;
    var child = parentEl.childNodes;
    var last = child[child.length - 1] || parentEl.lastChild;
    if (last === _this) {
        parentEl.appendChild(newEl);
    } else {
        parentEl.insertBefore(newEl, _this.nextSibling);
    }
    return newEl;
};

/**
*  使光标聚焦在该元素后面
* @param el 需要文字聚焦的 元素节点
*/
U.UF.E.Table.placeCaretAtEnd = function (el) {    //传入光标要去的节点对象
    if (el.collapse) {   //如果存在el.collapsed 则是range
        var range = el;
        range.collapse(false);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
        return;
    }
    if (typeof window.getSelection != "undefined" && typeof document.createRange != "undefined") {
        el.focus && el.focus();
        var range = document.createRange();
        range.selectNodeContents(el);
        range.collapse(false);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
    } else if (typeof document.body.createTextRange != "undefined") {
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(el);
        textRange.collapse(false);
        textRange.select();
    }
};

流程图:

Alternate Text

工作人员

 
作者: 15互联网G5-3 黄伟艺
信息录入: 15互联网G5-3 黄伟艺