迫蔺 发表于 2025-5-29 20:15:35

jQuery一步一步实现跨浏览器的可编辑表格

      在修改数据时,有时候为了方便,我们希望能够直接在表格里面对数据进行直接修改。
      要实现可编辑的表格功能,我们要解决以下问题:
            1.明确要修改的数据在表格中是哪些列(如何找到这些单元格);
            2.如何让单元格变成可以编辑的;
            3.如何处理单元格的一些按键事件;
            4.解决跨浏览器问题。

     我们通过jQuery可以一步一步解决上述问题。
     
 一、    绘制表格
 首先我们先画好一个表格。
     Code1:
Code




jQuery的跨浏览器可编辑表格






    
        
            
                鼠标点击表格就可以编辑
            
        
        
            
                学号
                姓名
            
            
                000001
                张三
            
            
                000002
                李四
            
            
                000003
                王五
            
            
                000004
                赵六
            
        
    


   画好表格以后显示的如图:
       editTable01.jpg
      

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


Code
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:


Code
$(document).ready(function(){
    //找到学号这一列的所有单元格
    //因为学号这一列的单元格在所有td中的位置是偶数(0,2,4,6),所以通过even就可以筛选到td中偶数位的单元格
    var numTd = $("tbody  td:even");
    
    //单击这些td时,创建文本框
    numTd.click(function(){
        //创建文本框对象
        var inputobj = $("");
        //获取当前点击的单元格对象
        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:
       

Code
$(document).ready(function(){
    //找到学号这一列的所有单元格
    //因为学号这一列的单元格在所有td中的位置是偶数(0,2,4,6),所以通过even就可以筛选到td中偶数位的单元格
    var numTd = $("tbody  td:even");
    
    //单击这些td时,创建文本框
    numTd.click(function(){
        //创建文本框对象
        var inputobj = $("");
        //获取当前点击的单元格对象
        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:

Code
$(document).ready(function(){
    //找到学号这一列的所有单元格
    //因为学号这一列的单元格在所有td中的位置是偶数(0,2,4,6),所以通过even就可以筛选到td中偶数位的单元格
    var numTd = $("tbody  td:even");
    
    //单击这些td时,创建文本框
    numTd.click(function(){
        //创建文本框对象
        var inputobj = $("");
        //获取当前点击的单元格对象
        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:

      
Code
$(document).ready(function(){
    //找到学号这一列的所有单元格
    //因为学号这一列的单元格在所有td中的位置是偶数(0,2,4,6),所以通过even就可以筛选到td中偶数位的单元格
    var numTd = $("tbody  td:even");
    
    //单击这些td时,创建文本框
    numTd.click(function(){
        //创建文本框对象
        var inputobj = $("");
        //获取当前点击的单元格对象
        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:

       

Code
        //处理文本框上回车和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:

      
Code
$(document).ready(function(){
    //找到学号这一列的所有单元格
    //因为学号这一列的单元格在所有td中的位置是偶数(0,2,4,6),所以通过even就可以筛选到td中偶数位的单元格
    var numTd = $("tbody  td:even");
    
    //单击这些td时,创建文本框
    numTd.click(function(){
        //创建文本框对象
        var inputobj = $("");
        //获取当前点击的单元格对象
        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);
            }
        });
        
    });
});      
       下面是源文件下载:/Files/psunny/EditTable.rar
 
出处:http://www.cnblogs.com/psunny/本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
页: [1]
查看完整版本: jQuery一步一步实现跨浏览器的可编辑表格