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 相关文章推荐
jquery之超简单的div显示和隐藏特效demo(分享)
Jul 09 Javascript
Js控制弹窗实现在任意分辨率下居中显示
Aug 01 Javascript
node.js中的fs.chown方法使用说明
Dec 16 Javascript
JavaScript实现网页对象拖放功能的方法
Apr 15 Javascript
浅谈jQuery中setInterval()方法
Jul 07 Javascript
jQuery获取页面及个元素高度、宽度的总结——超实用
Jul 28 Javascript
jQuery.Sumoselect插件实现下拉复选框效果
Nov 09 jQuery
AngularJs 禁止模板缓存的方法
Nov 28 Javascript
微信小程序实现点击按钮修改view标签背景颜色功能示例【附demo源码下载】
Dec 06 Javascript
vuex直接赋值的三种方法总结
Sep 16 Javascript
JS学习笔记之闭包小案例分析
May 29 Javascript
基于Vue实现电商SKU组合算法问题
May 29 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抽象工厂模式(Elgg)
2010/03/21 PHP
php选择排序法实现数组排序实例分析
2015/02/16 PHP
php简单统计字符串单词数量的方法
2015/06/19 PHP
如何使用PHP Embed SAPI实现Opcodes查看器
2015/11/10 PHP
PHP strcmp()和strcasecmp()的区别实例
2016/11/05 PHP
one.php 多项目、函数库、类库 统一为一个版本的方法
2020/08/24 PHP
ThinkPHP 5 AJAX跨域请求头设置实现过程解析
2020/10/28 PHP
玩转jQuery按钮 请告诉我你最喜欢哪些?
2012/01/08 Javascript
IE6下拉框图层问题探讨及解决
2014/01/03 Javascript
js操作模态窗口及父子窗口间相互传值示例
2014/06/09 Javascript
javascript使用正则表达式检测IP地址
2014/12/03 Javascript
JQuery记住用户名密码实现下次自动登录功能
2015/04/27 Javascript
jQuery抛物线运动实现方法(附完整demo源码下载)
2016/01/08 Javascript
JavaScript简单获取页面图片原始尺寸的方法
2016/06/21 Javascript
jQuery EasyUI 右键菜单--关闭标签/选项卡的简单实例
2016/10/10 Javascript
文件上传插件SWFUpload的使用指南
2016/11/29 Javascript
Angular directive递归实现目录树结构代码实例
2017/05/05 Javascript
Vue和Bootstrap的整合思路详解
2017/06/30 Javascript
vue检测对象和数组的变化分析
2018/06/30 Javascript
axios简单实现小程序延时loading指示
2018/07/30 Javascript
jQuery内容选择器与表单选择器实例分析
2019/06/28 jQuery
vue自定义组件实现双向绑定
2021/01/13 Vue.js
python实现ip代理池功能示例
2019/07/05 Python
python GUI库图形界面开发之PyQt5信号与槽多窗口数据传递详细使用方法与实例
2020/03/08 Python
使用html5制作loading图的示例
2014/04/14 HTML / CSS
Net Remoting把服务器端激活两种模式
2014/01/22 面试题
班主任对学生的评语
2014/04/26 职场文书
学校募捐倡议书
2014/05/14 职场文书
民政局办理协议离婚(范本)
2014/10/25 职场文书
工商局所长四风自我剖析及整改措施
2014/10/26 职场文书
齐云山导游词
2015/02/06 职场文书
工程技术员岗位职责
2015/04/11 职场文书
毕业生学校组织意见
2015/06/04 职场文书
在pycharm中无法import所安装的库解决方案
2021/05/31 Python
Python3.8官网文档之类的基础语法阅读
2021/09/04 Python
Windows server 2022创建创建林、域树、子域的步骤
2022/06/25 Servers