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 相关文章推荐
理解Javascript_02_理解undefined和null
Oct 11 Javascript
jquery应该如何来设置改变按钮input的onclick事件
Dec 10 Javascript
Extjs中ComboBoxTree实现的下拉框树效果(自写)
May 28 Javascript
JavaScript前补零操作实例
Mar 11 Javascript
基于JS实现的倒计时程序实例
Jul 24 Javascript
详解JavaScript中数组的相关知识
Jul 29 Javascript
用JavaScript来美化HTML的select标签的下拉列表效果
Nov 17 Javascript
javascript原生ajax写法分享
Apr 10 Javascript
微信小程序promsie.all和promise顺序执行
Oct 27 Javascript
vue-cli webpack模板项目搭建及打包时路径问题的解决方法
Feb 26 Javascript
JavaScript内置对象math,global功能与用法实例分析
Jun 10 Javascript
Vue 自定义标签的src属性不能使用相对路径的解决
Sep 17 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写的serv-u的web申请账号的程序
2006/10/09 PHP
PHP读取xml方法介绍
2013/01/12 PHP
php foreach循环中使用引用的问题
2013/11/06 PHP
19个超实用的PHP代码片段
2014/03/14 PHP
php使用Jpgraph绘制复杂X-Y坐标图的方法
2015/06/10 PHP
CI框架源码解读之URI.php中_fetch_uri_string()函数用法分析
2016/05/18 PHP
浅谈PHP正则中的捕获组与非捕获组
2016/07/18 PHP
PHP实现一维数组与二维数组去重功能示例
2018/05/24 PHP
js汉字转拼音实现代码
2013/02/06 Javascript
jQuery阻止同类型事件小结
2013/04/19 Javascript
2014年最火的Node.JS后端框架推荐
2014/10/27 Javascript
jQuery实现仿QQ头像闪烁效果的文字闪动提示代码
2015/11/03 Javascript
noty ? jQuery通知插件全面解析
2016/05/18 Javascript
Google Maps基础及实例解析
2016/08/06 Javascript
解析JavaScript实现DDoS攻击原理与保护措施
2016/12/26 Javascript
vue父子组件的数据传递示例
2017/03/07 Javascript
百度地图JavascriptApi Marker平滑移动及车头指向行径方向
2017/03/13 Javascript
用JavaScript和jQuery实现瀑布流
2017/03/19 Javascript
JQueryMiniUI按照时间进行查询的实现方法
2017/06/07 jQuery
vue2 中如何实现动态表单增删改查实例
2017/06/09 Javascript
vue2.0安装style/css loader的方法
2018/03/14 Javascript
js异步上传多张图片插件的使用方法
2018/10/22 Javascript
NodeJs实现简单的爬虫功能案例分析
2018/12/05 NodeJs
微信小程序将页面按钮悬浮固定在底部的实现代码
2020/10/29 Javascript
django-allauth入门学习和使用详解
2019/07/03 Python
Python中pymysql 模块的使用详解
2019/08/12 Python
django 外键创建注意事项说明
2020/05/20 Python
HTML5 placeholder(空白提示)属性介绍
2013/08/07 HTML / CSS
优质有机椰子产品:Dr. Goerg
2019/09/24 全球购物
一道SQL面试题
2012/12/31 面试题
金融专业推荐信
2013/11/14 职场文书
创业计划书中要认真思考的问题
2013/12/28 职场文书
英文商务邀请信
2014/01/22 职场文书
2014年道德讲堂实施方案
2014/03/05 职场文书
培训计划通知
2015/07/15 职场文书
SpringBoot项目中控制台日志的保存配置操作
2021/06/18 Java/Android