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

  要实现可编辑的表格功能,我们要解决以下问题:

  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

  很明显它看起来不像一个表格,既没有边框,而且很丑。那么我们先给这个表格设置一些样式。

  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

  但是单元格和单元格之间还是有重叠的边框,只需要在标签选择符table中加上这样一个属性就能去除重复边框:

  border-collapse: collapse;

  

复制代码 代码如下:

  table{}{

  color: #4F6B72;

  border: 1px solid #C1DAD7;

  border-collapse: collapse;

  width: 400px;

  }

  editTable03.jpg

  二、 让表格的单元格变成可编辑的列

  绘制好表格以后,我们选取表格中的编号列作为可编辑的列。要让这一列的单元格能够被编辑,就需要在这些列中插入文本框,我们通过这一列单元格的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

  但是有个明显的bug,当你再次点击同一个单元格时,会出现如下效果:

          editTable05.jpg

  

  

  是什么原因造成上面这个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);

  }

  });

  });

  });

  相关文档打包下载