用js实现table单元格高宽调整,兼容合并单元格(兼容IE6、7、8、FF)实例


Posted in Javascript onJune 25, 2013

先上效果图:

用js实现table单元格高宽调整,兼容合并单元格(兼容IE6、7、8、FF)实例

CSS:

body{margin:0px;padding:0px;-moz-user-select:none;cursor:default;}
.tabEditDiv{position:absolute;width:15px;height:15px;cursor:pointer;}
.seltab{position:absolute;width:15px;height:15px;cursor:pointer;background:url(images/seltab.gif) no-repeat;}
.splitx{overflow:hidden;position:absolute;height:3px;cursor:row-resize;background:red !important;filter:Alpha(opacity=10);-moz-opacity:0.1;opacity: 0.1; }
.splity{overflow:hidden;position:absolute;width:3px;cursor:col-resize;background:red !important;filter:Alpha(opacity=10);-moz-opacity:0.1;opacity: 0.1;}
#tabletitle{font-weight:bold;font-size:18px;height:30px;width:800px;margin:0 auto;text-align:center;font-family:宋体;line-height:30px;}
#tabletitle input{width:100%;border:0px;height:28px;line-height:30px;text-align:center;font-weight:bold;font-size:18px;font-family:宋体;}
.finelinetable{border-right:1px solid #000;border-top:1px solid #000;border-collapse:collapse;font-size:13px;width:800px;margin:0 auto;}
.finelinetable td{border-left:1px solid #000;border-bottom:1px solid #000;height:25px;}

HTML:

<body>
     <div id="tabletitle">表格标题</div>
     <table id="mainTable" class="finelinetable">
         <tr>
             <td colspan="8">1</td>
         </tr>
         <tr>
             <td rowspan="3">2</td>
             <td>3</td>
             <td colspan="3">4</td>
             <td>5</td>
             <td>6</td>
             <td>7</td>
         </tr>
         <tr>
             <td>8</td>
             <td>9</td>
             <td>10</td>
             <td colspan="2">11</td>
             <td>12</td>
             <td>13</td>
         </tr>
         <tr>
             <td>14</td>
             <td colspan="3">15</td>
             <td>16</td>
             <td>17</td>
             <td>18</td>
         </tr>
         <tr>
             <td colspan="8"> </td>
         </tr>
         <tr>
             <td rowspan="3"> </td>
             <td> </td>
             <td colspan="2"> </td>
             <td> </td>
             <td colspan="3"> </td>
         </tr>
         <tr>
             <td> </td>
             <td colspan="2"> </td>
             <td> </td>
             <td colspan="3"> </td>
         </tr>
         <tr>
             <td style="height: 25px"> </td>
             <td colspan="2" style="height: 25px"> </td>
             <td style="height: 25px"> </td>
             <td colspan="3" style="height: 25px"> </td>
         </tr>
         <tr>
             <td> </td>
             <td colspan="7"> </td>
         </tr>
         <tr>
             <td colspan="2"> </td>
             <td colspan="6"> </td>
         </tr>
         <tr>
             <td colspan="2"> </td>
             <td colspan="6"> </td>
         </tr>
         <tr>
             <td colspan="2"> </td>
             <td colspan="6"> </td>
         </tr>
     </table>
 </body>

JS:

//注释:获取对象.示例:$("objectId") 等同于 document.getElementById("objectId")
 if (typeof $ != "function") { var $ = function (ids) { return document.getElementById(ids) }; }
 //注释:获取坐标,parentNode最后节点.示例:absPos(object).x
 function absPos(_node, parentNode) { var x = y = 0; var node = _node; do { if (parentNode && node == parentNode) { break; } x += node.offsetLeft; y += node.offsetTop; } while (node = node.offsetParent); node = _node; return { 'x': x, 'y': y }; }
 function addEvent(object, event, func) { if (object.addEventListener) { /* W3C方法(DOM方法)下面语句中的false意思是用于冒泡阶段,若是true则是用于捕获阶段(IE不支持捕获),所以这里用false是一方面的原因是为了统一 */object.addEventListener(event, func, false); return true; } else if (object.attachEvent) { /* MSIE方法(IE方法) */object['e' + event + func] = func; object[event + func] = function () { object['e' + event + func](window.event); }; object.attachEvent('on' + event, object[event + func]); return true; } /*如两种方法都不具备则返回false */return false; }
 //注释:判断是否是对象内子节点触发的onmouseover和onmouseout.示例:e = e || event;if (isMouseLeaveOrEnter(e, obj)) {}
 function isMouseLeaveOrEnter(e, handler) { if (e.type != 'mouseout' && e.type != 'mouseover') return false; var reltg = e.relatedTarget ? e.relatedTarget : e.type == 'mouseout' ? e.toElement : e.fromElement; while (reltg && reltg != handler) reltg = reltg.parentNode; return (reltg != handler); } var table = $("mainTable");
 var tabEditDiv; //覆盖在table上的DIV
 var cellHide = [];//补充的rowspan,cellspan的格子
 var moveMode = "";//鼠标移动模式
 var moveArgs = []; //移动模式参数
 document.onselectstart = function(){return false;};
 addEvent(window,"resize",function(){loadTable();});
 $("tabletitle").ondblclick = function(){
     if(this.getElementsByTagName("input").length > 0){return;}
     this.innerHTML = "<input type='text' value='" + (this.innerHTML == "表格标题" ? "" : this.innerHTML) + "' />";
     var input = this.getElementsByTagName("input")[0];
     var _this = this;
     input.focus();
     input.onblur = function(){_this.innerHTML = this.value;}
     input.onkeydown = function (e) { var key = window.event ? window.event.keyCode : e.which; if (key == 13) this.blur(); };
 }
 function loadTable(){
     var tabPos = absPos(table);
     if(!tabEditDiv){
         tabEditDiv = document.createElement("div");
         document.body.appendChild(tabEditDiv);
     }
     tabEditDiv.style.cssText = "left:" + (tabPos.x - 15) + "px;top:" + (tabPos.y - 15) + "px;";
     tabEditDiv.className = "tabEditDiv";
     //全选Table按钮
     if(!seltab){
         var seltab = document.createElement("div"); 
         seltab.style.cssText = "width:15px;height:15px;left:" + (tabPos.x - 15) + "px;top:" + (tabPos.y - 15) + "px;";
         seltab.className = "seltab";
         seltab.onclick = function(){
             if(table.getAttribute("selected") == "1"){
                 table.removeAttribute("selected");
                 table.style.background = "";
                 this.style.width = "15px";
                 this.style.height = "15px";
             }else{
                 table.setAttribute("selected","1");
                 table.style.background = "#B6CAEB";
                 this.style.width = (table.clientWidth + 15) + "px";
                 this.style.height = (table.clientHeight + 15) + "px";
             }
         }
         document.body.appendChild(seltab);
     }
     loadTableEdit();
 } loadTable();
 function loadTableEdit(){ //加载可调整宽度及高度的div
     var tabPos = absPos(table);
     tabEditDiv.innerHTML = "";
     var cellcount = 0;
     var isadd = cellHide.length == 0;
     for(var i=0;i<table.rows.length;i++){
         for(var j=0;j<table.rows[i].cells.length;j++){
             var pos = absPos(table.rows[i].cells[j],table);
             if(!$("splitx_" + (pos.y + table.rows[i].cells[j].clientHeight))){ //加载可调整高度的div
                 var split = document.createElement("div");
                 split.id = "splitx_" + (pos.y + table.rows[i].cells[j].clientHeight);
                 split.className = "splitx";
                 split.style.cssText = "width:" + table.clientWidth + "px;left:15px;top:" + (pos.y + table.rows[i].cells[j].clientHeight - 1 + 15) + "px";
                 split.onmousedown = function(){
                     var index = this.getAttribute("index");
                     if(index == null){ index = 0; var divs = tabEditDiv.getElementsByTagName("div"); var left = parseInt(this.id.split("_")[1]); for(var k=0;k<divs.length;k++){ if(divs[k].id.indexOf("splitx_") < 0) continue; if(parseInt(divs[k].id.split("_")[1]) < left) index++; } this.setAttribute("index",index);}else{index = parseInt(index);}
                     moveMode = "cellHeight";
                     moveArgs[moveArgs.length] = index;
                 }
                 tabEditDiv.appendChild(split);
             }
             if(j > 0){ //加载可调整宽度的div
                 if(!$("splity_" + pos.x)){
                     var split = document.createElement("div");
                     split.id = "splity_" + pos.x;
                     split.className = "splity";
                     split.style.cssText = "height:" + table.clientHeight + "px;top:15px;left:" + (pos.x - 2 + 15) + "px";
                     split.onmousedown = function(){
                         var index = this.getAttribute("index");
                         if(index == null){ index = 0; var divs = tabEditDiv.getElementsByTagName("div"); var left = parseInt(this.id.split("_")[1]); for(var k=0;k<divs.length;k++){ if(divs[k].id.indexOf("splity_") < 0) continue; if(parseInt(divs[k].id.split("_")[1]) < left) index++; } this.setAttribute("index",index);}else{index = parseInt(index);}
                         moveMode = "cellWidth";
                         moveArgs[moveArgs.length] = index;
                     }
                     tabEditDiv.appendChild(split);
                 }
             }
             if(isadd){
                 loadHide();
             }
             table.rows[i].cells[j].onmousedown = function(){
                 //alert("x");
             }
         }
     }
 }
 function loadHide(){
     cellHide = [];
     var tempHide = [];
     for(var i=0;i<table.rows.length;i++){
         for(var j=0;j<table.rows[i].cells.length;j++){
             for(var k=1;k<table.rows[i].cells[j].rowSpan;k++){
                 cellHide[cellHide.length] = [i+k,j];
                 tempHide[tempHide.length] = [i+k,j];
             }
         }
     }
     for(var i=0;i<table.rows.length;i++){
         for(var j=0;j<table.rows[i].cells.length;j++){
             for(var k=1;k<table.rows[i].cells[j].colSpan;k++){
                 var yc = 0;
                 for(var l=0;l<tempHide.length;l++){
                     if(tempHide[l][0]==i&&tempHide[l][1]<j){yc++;}
                 }
                 for(var l=0;l<j;l++){
                     if(table.rows[i].cells[l].colSpan > 1){yc+=table.rows[i].cells[l].colSpan-1;}
                 }
                 cellHide[cellHide.length] = [i,j+k+yc];
             }
         }
     }
 }
 addEvent(document,"mousemove",function(e){
     e = e || window.event;
     if(moveMode == "cellWidth"){ //调整宽度
         var temp = moveArgs[0];
         var test = "";
         for(var i=0;i<table.rows.length;i++){
             var index = temp;
             for(var j=0;j<cellHide.length;j++){
                 if(i==cellHide[j][0] && temp>=cellHide[j][1]){index--;}
             }
             if(!table.rows[i].cells[index] || index < 0 || table.rows[i].cells[index].colSpan > 1){continue;}
             if(e.clientX > absPos(table.rows[i].cells[index]).x)
                 table.rows[i].cells[index].style.width = e.clientX - absPos(table.rows[i].cells[index]).x + "px";
         }
         loadTableEdit();
     }else if(moveMode == "cellHeight"){ //调整高度
         var index = moveArgs[0];
         for(var i=0;i<table.rows[index].cells.length;i++){
             if(table.rows[index].cells[i].rowSpan > 1){continue;}
             if(e.clientY > absPos(table.rows[index].cells[i]).y)
                 table.rows[index].cells[i].style.height = e.clientY - absPos(table.rows[index].cells[i]).y + "px";
         }
         loadTableEdit();
     }
 });
 addEvent(document,"mouseup",function(e){
     moveMode = ""; moveArgs = [];
 });
 addEvent(document,"mouseout",function(e){
     e = e || event;
     if (!isMouseLeaveOrEnter(e, this)) { return; }
     moveMode = ""; moveArgs = [];
 });
Javascript 相关文章推荐
jQuery 开天辟地入门篇一
Dec 09 Javascript
关于文本框的一些限制控制总结~~
Apr 15 Javascript
高亮显示web页表格行的javascript代码
Nov 19 Javascript
setTimeout函数兼容各主流浏览器运行执行效果实例
Jun 13 Javascript
jQuery如何防止Ajax重复提交
Oct 14 Javascript
基于jQuery实现滚动切换效果
Dec 02 Javascript
详解Sea.js中Module.exports和exports的区别
Feb 12 Javascript
Node.js实现文件上传的示例
Jun 28 Javascript
javascript  删除select中的所有option的实例
Sep 17 Javascript
简述vue-cli中chainWebpack的使用方法
Jul 30 Javascript
vue2.0 获取从http接口中获取数据,组件开发,路由配置方式
Nov 04 Javascript
Vue中避免滥用this去读取data中数据
Mar 02 Vue.js
javascript实现div的显示和隐藏的小例子
Jun 25 #Javascript
js中复制行和删除行的操作实例
Jun 25 #Javascript
JQuery+DIV自定义滚动条样式的具体实现
Jun 25 #Javascript
js循环改变div颜色具体方法
Jun 25 #Javascript
js点击更换背景颜色或图片的实例代码
Jun 25 #Javascript
js操作iframe的一些方法介绍
Jun 25 #Javascript
动态获取复选框checkbox选中个数的jquery代码
Jun 25 #Javascript
You might like
php初始化对象和析构函数的简单实例
2014/03/11 PHP
Linux安装配置php环境的方法
2016/01/14 PHP
php中array_slice和array_splice函数解析
2016/10/18 PHP
php ajax confirm 删除实例详解
2019/03/06 PHP
JS是否可以跨文件同时控制多个iframe页面的应用技巧
2007/12/16 Javascript
一段利用WSH修改和查看IP配置的代码
2008/05/11 Javascript
javaScript parseInt字符转化为数字函数使用小结
2009/11/05 Javascript
javascript中的array数组使用技巧
2010/01/31 Javascript
javascript判断非数字的简单例子
2013/07/18 Javascript
jQuery实现鼠标滑过Div层背景变颜色的方法
2015/02/17 Javascript
jQuery实现分章节锚点“回到顶部”动画特效代码
2015/10/23 Javascript
JavaScript reduce和reduceRight详解
2016/10/24 Javascript
Angular.js实现注册系统的实例详解
2016/12/18 Javascript
浅谈jQuery中事情的动态绑定
2017/02/12 Javascript
JavaScript中值类型和引用类型的区别
2017/02/23 Javascript
Node.js中Bootstrap-table的两种分页的实现方法
2017/09/18 Javascript
微信小程序template模板实例详解
2017/10/27 Javascript
VUE项目初建和常见问题总结
2019/09/12 Javascript
vue各种事件监听实例(小结)
2020/06/24 Javascript
基于vue与element实现创建试卷相关功能(实例代码)
2020/12/07 Vue.js
[01:25]DOTA2自定义游戏灵园鬼域等你踏足
2015/10/30 DOTA
Python 中的with关键字使用详解
2016/09/11 Python
python实现多人聊天室
2020/03/31 Python
python 获取url中的参数列表实例
2018/12/18 Python
Python实现读取txt文件中的数据并绘制出图形操作示例
2019/02/26 Python
详解python selenium 爬取网易云音乐歌单名
2019/03/28 Python
5行Python代码实现图像分割的步骤详解
2020/05/25 Python
matplotlib交互式数据光标实现(mplcursors)
2021/01/13 Python
大学校园生活自我鉴定
2014/01/13 职场文书
优乐美广告词
2014/03/14 职场文书
战友聚会主持词
2014/04/02 职场文书
幼儿园课题实施方案
2014/05/14 职场文书
2014年外贸业务员工作总结
2014/12/11 职场文书
教学质量月活动总结
2015/05/11 职场文书
孔繁森观后感
2015/06/10 职场文书
pytorch 实现多个Dataloader同时训练
2021/05/29 Python