jQuery一步一步实现跨浏览器的可编辑表格,支持IE、Firefox、Safari、Chrome、Opera


Posted in Javascript onAugust 28, 2009

要实现可编辑的表格功能,我们要解决以下问题:
1.明确要修改的数据在表格中是哪些列(如何找到这些单元格);
2.如何让单元格变成可以编辑的;
3.如何处理单元格的一些按键事件;
4.解决跨浏览器问题。
我们通过jQuery可以一步一步解决上述问题。
一、 绘制表格
首先我们先画好一个表格。
Code1:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>jQuery的跨浏览器可编辑表格</title> 
<link rel="stylesheet" type="text/css" href="css/editTable.css" media="all"/> 
<script type="text/javascript" src="js/jquery-1.3.2.min.js"></script> 
<script type="text/javascript" src="js/editTable.js"></script> 
</head> 
<body> 
<table> 
<thead> 
<tr> 
<th colspan="2">鼠标点击表格就可以编辑</th> 
</tr> 
</thead> 
<tbody> 
<tr> 
<th>学号</th> 
<th>姓名</th> 
</tr> 
<tr> 
<td>000001</td> 
<td>张三</td> 
</tr> 
<tr> 
<td>000002</td> 
<td>李四</td> 
</tr> 
<tr> 
<td>000003</td> 
<td>王五</td> 
</tr> 
<tr> 
<td>000004</td> 
<td>赵六</td> 
</tr> 
</tbody> 
</table> 
</body> 
</html>

画好表格以后显示的如图:
editTable01.jpg
jQuery一步一步实现跨浏览器的可编辑表格,支持IE、Firefox、Safari、Chrome、Opera 
很明显它看起来不像一个表格,既没有边框,而且很丑。那么我们先给这个表格设置一些样式。
Code2:
body{}{ 
font-size: 14px; 
} 
table{}{ 
color: #4F6B72; 
border: 1px solid #C1DAD7; 
border-collapse: collapse; 
width: 400px; 
} 
th{}{ 
width: 50%; 
border: 1px solid #C1DAD7; 
} 
td{}{ 
width: 50%; 
border: 1px solid #C1DAD7; 
}

现在效果好多了:
editTable02.jpg
jQuery一步一步实现跨浏览器的可编辑表格,支持IE、Firefox、Safari、Chrome、Opera     
但是单元格和单元格之间还是有重叠的边框,只需要在标签选择符table中加上这样一个属性就能去除重复边框:
border-collapse: collapse;
table{}{ 
color: #4F6B72; 
border: 1px solid #C1DAD7; 
border-collapse: collapse; 
width: 400px; 
}

editTable03.jpg
jQuery一步一步实现跨浏览器的可编辑表格,支持IE、Firefox、Safari、Chrome、Opera
二、 让表格的单元格变成可编辑的列
绘制好表格以后,我们选取表格中的编号列作为可编辑的列。要让这一列的单元格能够被编辑,就需要在这些列中插入文本框,我们通过这一列单元格的onclick事件来插入文本框。
Code3:
$(document).ready(function(){ 
//找到学号这一列的所有单元格 
//因为学号这一列的单元格在所有td中的位置是偶数(0,2,4,6),所以通过even就可以筛选到td中偶数位的单元格 
var numTd = $("tbody td:even"); 
//单击这些td时,创建文本框 
numTd.click(function(){ 
//创建文本框对象 
var inputobj = $("<input type='text'>"); 
//获取当前点击的单元格对象 
var tdobj = $(this); 
//去除文本框的border 
inputobj.css("border","0"); 
//让文本框和单元格的宽度保持一致 
inputobj.width(tdobj.width()); 
//让文本框的字体和单元格的字体大小一样 
inputobj.css("font-size",tdobj.css("font-size")); 
//让文本框和单元格的字体保持一致 
inputobj.css("font-family",tdobj.css("font-family")); 
//让文本框和单元格的背景保持一致 
inputobj.css("background-color",tdobj.css("background-color")); 
//appendTo方法把文本框添加到td中 
inputobj.appendTo(tdobj); 
}); 
});

现在已经把文本框插入到单元格中了。既然要编辑文本框,文本框就应该有值,文本框的值来源于单元格中的数据,并且我们要清空单元格中原有的数据。
Code4:
$(document).ready(function(){ 
//找到学号这一列的所有单元格 
//因为学号这一列的单元格在所有td中的位置是偶数(0,2,4,6),所以通过even就可以筛选到td中偶数位的单元格 
var numTd = $("tbody td:even"); 
//单击这些td时,创建文本框 
numTd.click(function(){ 
//创建文本框对象 
var inputobj = $("<input type='text'>"); 
//获取当前点击的单元格对象 
var tdobj = $(this); 
//获取单元格中的文本 
var text = tdobj.html(); 
//清空单元格的文本 
tdobj.html(""); 
//去除文本框的border 
inputobj.css("border","0"); 
//让文本框和单元格的宽度保持一致 
inputobj.width(tdobj.width()); 
//让文本框的字体和单元格的字体大小一样 
inputobj.css("font-size",tdobj.css("font-size")); 
//让文本框和单元格的字体保持一致 
inputobj.css("font-family",tdobj.css("font-family")); 
//让文本框和单元格的背景保持一致 
inputobj.css("background-color",tdobj.css("background-color")); 
inputobj.css("color","#C75F3E"); 
//给文本框赋值 
inputobj.val(text); 
//appendTo方法把文本框添加到td中 
inputobj.appendTo(tdobj); 
}); 
});

但是以上代码看起来非常的繁琐,jQuery有一个非常好的优点,就是它的代码连缀。上面的代码可以通过连缀进行简化:
Code5:
$(document).ready(function(){ 
//找到学号这一列的所有单元格 
//因为学号这一列的单元格在所有td中的位置是偶数(0,2,4,6),所以通过even就可以筛选到td中偶数位的单元格 
var numTd = $("tbody td:even"); 
//单击这些td时,创建文本框 
numTd.click(function(){ 
//创建文本框对象 
var inputobj = $("<input type='text'>"); 
//获取当前点击的单元格对象 
var tdobj = $(this); 
//获取单元格中的文本 
var text = tdobj.html(); 
//清空单元格的文本 
tdobj.html(""); 
inputobj.css("border","0") 
.css("font-size",tdobj.css("font-size")) 
.css("font-family",tdobj.css("font-family")) 
.css("background-color",tdobj.css("background-color")) 
.css("color","#C75F3E") 
.width(tdobj.width()) 
.val(text) 
.appendTo(tdobj); 
}); 
});

现在表格中已经成功的插入了文本框,可以对单元格进行编辑了。
editTable04.jpg
jQuery一步一步实现跨浏览器的可编辑表格,支持IE、Firefox、Safari、Chrome、Opera       
    但是有个明显的bug,当你再次点击同一个单元格时,会出现如下效果:

        editTable05.jpg

      
jQuery一步一步实现跨浏览器的可编辑表格,支持IE、Firefox、Safari、Chrome、Opera 
是什么原因造成上面这个bug呢?因为在文本框中插入单元格之后,文本框是属于单元格的,我们点击文本框时,同样会触发单元格的click事件。
我们需要阻止文本框的点击行为(阻止事件冒泡)。
Code6:

inputobj.click(function(){ 
return false; 
});

但是点击单元格的边框时,还是会出现上述的bug,那我们做如下判断:如果单元格中已经插入了文本框,就跳出click事件。
Code7:
$(document).ready(function(){ 
//找到学号这一列的所有单元格 
//因为学号这一列的单元格在所有td中的位置是偶数(0,2,4,6),所以通过even就可以筛选到td中偶数位的单元格 
var numTd = $("tbody td:even"); 
//单击这些td时,创建文本框 
numTd.click(function(){ 
//创建文本框对象 
var inputobj = $("<input type='text'>"); 
//获取当前点击的单元格对象 
var tdobj = $(this); 
//获取单元格中的文本 
var text = tdobj.html(); 
//如果当前单元格中有文本框,就直接跳出方法 
//注意:一定要在插入文本框前进行判断 
if(tdobj.children("input").length>0){ 
return false; 
} 
//清空单元格的文本 
tdobj.html(""); 
inputobj.css("border","0") 
.css("font-size",tdobj.css("font-size")) 
.css("font-family",tdobj.css("font-family")) 
.css("background-color",tdobj.css("background-color")) 
.css("color","#C75F3E") 
.width(tdobj.width()) 
.val(text) 
.appendTo(tdobj); 
inputobj.get(0).select(); 
//阻止文本框的点击事件 
inputobj.click(function(){ 
return false; 
}); 
}); 
});

上面的bug解决了,但是我发现,点击单元格时,虽然从表面上看文字是变了色,但没有让我觉得它是能被编辑的。那么我就做一点点的改动,插入文本框的同时,选中文本框的文本。
Code 8:
inputobj.get(0).select();

但是问题又来了,在Safari浏览器中,要让文本框处于选中状态,必须显得让文本框获得焦点。而我们这里只是在点击单元格时,插入文本框并给文本框赋值,文本框并没有获得焦点。解决的方法:通过jQuery的trigger方法来触发某个事件。
Code9:
inputobj.trigger("focus").trigger("select");

三、文本框按键事件处理
以上的这些问题解决了,那我们就再来给文本框添加一些按键事件。我们知道不同的浏览器中获取按键的keyCode是不同的,但是jQuery帮我们解决了这个问题。
只需要在事件的function中加入event参数,然后在方法体中,通过event对象的which属性就能获得keyCode,event.which属性同化了不同浏览器获取keyCode的方法。
获得keyCode之后,我主要做两个按键事件:ESC键(键值:27)和Enter键(键值:13)。
Code10:
//处理文本框上回车和esc按键的操作 
//jQuery中某个事件方法的function可以定义一个event参数,jQuery会屏蔽浏览器的差异,传递给我们一个可用的event对象 
inputobj.keyup(function(event){ 
//获取当前按键的键值 
//jQuery的event对象上有一个which的属性可以获得键盘按键的键值 
var keycode = event.which; 
//处理回车的情况 
if(keycode==13){ 
//获取当前文本框的内容 
var inputtext = $(this).val(); 
//将td的内容修改成文本框中的内容 
tdobj.html(inputtext); 
} 
//处理esc的情况 
if(keycode == 27){ 
//将td中的内容还原成text 
tdobj.html(text); 
} 
});

下面是完整的js代码:
Code11:
$(document).ready(function(){ 
//找到学号这一列的所有单元格 
//因为学号这一列的单元格在所有td中的位置是偶数(0,2,4,6),所以通过even就可以筛选到td中偶数位的单元格 
var numTd = $("tbody td:even"); 
//单击这些td时,创建文本框 
numTd.click(function(){ 
//创建文本框对象 
var inputobj = $("<input type='text'>"); 
//获取当前点击的单元格对象 
var tdobj = $(this); 
//获取单元格中的文本 
var text = tdobj.html(); 
//如果当前单元格中有文本框,就直接跳出方法 
//注意:一定要在插入文本框前进行判断 
if(tdobj.children("input").length>0){ 
return false; 
} 
//清空单元格的文本 
tdobj.html(""); 
inputobj.css("border","0") 
.css("font-size",tdobj.css("font-size")) 
.css("font-family",tdobj.css("font-family")) 
.css("background-color",tdobj.css("background-color")) 
.css("color","#C75F3E") 
.width(tdobj.width()) 
.val(text) 
.appendTo(tdobj); 
inputobj.get(0).select(); 
//阻止文本框的点击事件 
inputobj.click(function(){ 
return false; 
}); 
//处理文本框上回车和esc按键的操作 
//jQuery中某个事件方法的function可以定义一个event参数,jQuery会屏蔽浏览器的差异,传递给我们一个可用的event对象 
inputobj.keyup(function(event){ 
//获取当前按键的键值 
//jQuery的event对象上有一个which的属性可以获得键盘按键的键值 
var keycode = event.which; 
//处理回车的情况 
if(keycode==13){ 
//获取当前文本框的内容 
var inputtext = $(this).val(); 
//将td的内容修改成文本框中的内容 
tdobj.html(inputtext); 
} 
//处理esc的情况 
if(keycode == 27){ 
//将td中的内容还原成text 
tdobj.html(text); 
} 
}); 
}); 
});

相关文档打包下载

Javascript 相关文章推荐
Dom 是什么的详细说明
Oct 25 Javascript
原生javascript实现无间缝滚动示例
Jan 28 Javascript
JavaScript对象数组排序函数及六个用法
Dec 23 Javascript
AngularJS实现DOM元素的显示与隐藏功能
Nov 22 Javascript
javascript获取以及设置光标位置
Feb 16 Javascript
jQuery 控制文本框自动缩小字体填充
Jun 16 jQuery
webpack-dev-server远程访问配置方法
Feb 22 Javascript
详解extract-text-webpack-plugin 的使用及安装
Jun 12 Javascript
vue-router 源码实现前端路由的两种方式
Jul 02 Javascript
jQuery pagination分页示例详解
Oct 23 jQuery
Vue-cli打包后部署到子目录下的路径问题说明
Sep 02 Javascript
Javascript的promise,async和await的区别详解
Mar 24 Javascript
javascript 遍历验证所有文本框的值
Aug 27 #Javascript
JQuery 浮动导航栏实现代码
Aug 27 #Javascript
jQuery ui1.7 dialog只能弹出一次问题
Aug 27 #Javascript
JSON 客户端和服务器端的格式转换
Aug 27 #Javascript
动态表格Table类的实现
Aug 26 #Javascript
javascript 函数调用规则
Aug 26 #Javascript
JSON 入门指南 想了解json的朋友可以看下
Aug 26 #Javascript
You might like
PHP新手上路(六)
2006/10/09 PHP
最令PHP初学者们头痛的十四个问题
2007/01/15 PHP
php下批量挂马和批量清马代码
2011/02/27 PHP
php 求质素(素数) 的实现代码
2011/04/12 PHP
php常用的url处理函数总结
2014/11/19 PHP
php去除字符串中空字符的常用方法小结
2015/03/17 PHP
php计算多维数组中所有值总和的方法
2015/06/24 PHP
javascript中的注释使用与注意事项小结
2011/09/20 Javascript
jQuery LigerUI 使用教程入门篇
2012/01/18 Javascript
JavaScript中的单引号和双引号报错的解决方法
2014/09/01 Javascript
javascript实现图片上传前台页面
2015/08/18 Javascript
element 结合vue 在表单验证时有值却提示错误的解决办法
2018/01/22 Javascript
手写Node静态资源服务器的实现方法
2018/03/20 Javascript
jQuery中ajax请求后台返回json数据并渲染HTML的方法
2018/08/08 jQuery
js实现轮播图的完整代码
2020/10/26 Javascript
详解jQuery中的easyui
2018/09/02 jQuery
解决cordova+vue 项目打包成APK应用遇到的问题
2019/05/10 Javascript
[04:48]DOTA2上海特锦赛小组赛第三日 TOP10精彩集锦
2016/02/28 DOTA
Python运算符重载用法实例
2015/05/28 Python
Win8.1下安装Python3.6提示0x80240017错误的解决方法
2018/07/31 Python
python中单例常用的几种实现方法总结
2018/10/13 Python
keras获得model中某一层的某一个Tensor的输出维度教程
2020/01/24 Python
python使用OpenCV模块实现图像的融合示例代码
2020/04/10 Python
css3学习之2D转换功能详解
2016/12/23 HTML / CSS
html5调用摄像头功能的实现代码
2018/05/07 HTML / CSS
HTML5不支持标签和新增标签详解
2016/06/27 HTML / CSS
护士实习鉴定范文
2013/12/22 职场文书
元宵节晚会主持人串词
2014/03/25 职场文书
群众路线个人剖析材料
2014/10/07 职场文书
学校教学工作总结2015
2015/05/19 职场文书
学习习近平主席讲话心得体会
2016/01/20 职场文书
导游词之南京莫愁湖公园
2019/11/13 职场文书
pandas:get_dummies()与pd.factorize()的用法及区别说明
2021/05/21 Python
python not运算符的实例用法
2021/06/30 Python
Mybatis-Plus进阶分页与乐观锁插件及通用枚举和多数据源详解
2022/03/21 Java/Android
如何用H5实现好玩的2048小游戏
2022/07/23 HTML / CSS