用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 相关文章推荐
解决表单中第一个非隐藏的元素获得焦点的一个方案
Oct 26 Javascript
同一个网页中实现多个JavaScript特效的方法
Feb 02 Javascript
Javascript中的Prototype到底是什么
Feb 16 Javascript
JavaScript禁止复制与粘贴的实现代码
May 16 Javascript
jQuery实现产品对比功能附源码下载
Aug 09 Javascript
js自调用匿名函数的三种写法(推荐)
Aug 19 Javascript
Vue.js实现文章评论和回复评论功能
May 30 Javascript
基于vue-cli创建的项目的目录结构及说明介绍
Nov 23 Javascript
axios向后台传递数组作为参数的方法
Aug 11 Javascript
vuedraggable+element ui实现页面控件拖拽排序效果
Jul 29 Javascript
新年快乐! javascript实现超级炫酷的3D烟花特效
Jan 30 Javascript
详解Vue+elementUI build打包部署后字体图标丢失问题
Jul 13 Javascript
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
AJAX for PHP简单表数据查询实例
2007/01/02 PHP
PHP 变量定义和变量替换的方法
2009/07/30 PHP
PHP 开源框架22个简单简介
2009/08/24 PHP
PHP性能优化 产生高度优化代码
2011/07/22 PHP
PHP将字符分解为多个字符串的方法
2014/11/22 PHP
Yii配置文件用法详解
2014/12/04 PHP
jquery checkbox全选、取消全选实现代码
2010/03/05 Javascript
JS声明变量背后的编译原理剖析
2012/12/28 Javascript
实用的Jquery选项卡TAB示例代码
2013/08/28 Javascript
Ajax提交与传统表单提交的区别说明
2014/02/07 Javascript
js实现飞入星星特效代码
2014/10/17 Javascript
javascript中函数作为参数调用的方法
2015/02/09 Javascript
javascript实现一个数值加法函数
2015/06/26 Javascript
JavaScript动态改变div属性的实现方法
2015/07/22 Javascript
jQuery扩展_动力节点Java学院整理
2017/07/05 jQuery
jquery 一键复制到剪切板的实例
2017/09/20 jQuery
socket io与vue-cli的结合使用的示例代码
2018/11/01 Javascript
Node.js 实现抢票小工具 &amp; 短信通知提醒功能
2019/10/22 Javascript
axios如何取消重复无用的请求详解
2019/12/15 Javascript
浅析 Vue 3.0 的组装式 API(一)
2020/08/31 Javascript
[00:52]DOTA2第二届亚洲邀请赛预选赛宣传片
2017/01/13 DOTA
基于wxpython开发的简单gui计算器实例
2015/05/30 Python
详解Python发送邮件实例
2016/01/10 Python
Python 实现opencv所使用的图片格式与 base64 转换
2020/01/09 Python
Tensorflow:转置函数 transpose的使用详解
2020/02/11 Python
Pycharm中安装wordcloud等库失败问题及终端通过pip安装的Python库如何添加到Pycharm解释器中(推荐)
2020/05/10 Python
Python实现寻找回文数字过程解析
2020/06/09 Python
使用bandit对目标python代码进行安全函数扫描的案例分析
2021/01/27 Python
Python爬取梨视频的示例
2021/01/29 Python
英国最大的独立玩具专卖店:The Entertainer
2019/09/06 全球购物
中间件分为哪几类
2012/03/14 面试题
基层工作经历证明
2014/01/13 职场文书
学校募捐倡议书
2014/05/14 职场文书
2016年元旦主持词
2015/07/06 职场文书
六一儿童节园长致辞
2015/07/31 职场文书
Elasticsearch 基本查询和组合查询
2022/04/19 Python