JS可编辑表格
1.实现的功能
- 表格可编辑的部分单击就可以生成一个输入框,并且自动获取输入框焦点
- 在输入框输入修改的内容之后,当输入框失去焦点的时候就会判断输入的内容是否满足条件。
- 如果满足条件就修改内容,如果不满足条件就弹出提示
- 修改的内容再修改原始的数据
具体可以看如下图片
点击生成输入框
输入内容
完成修改
如果不满足条件就会返回原始值
其他的各项数据操作基本相同
2.实现的思路
- 首先在页面上生成表格的表头thead部分,然后tbody部分留空
- 然后在JS里面写入数据,用写的数据动态生成tbody部分,生成的部分可以修改,并且用setAttribute给生成的部分加上一个name属性
- 然后用dom操作找出刚才动态生成的表单内容,点击就生成一个input框,用来修改数据。并且要注意不能多次点击就可以用this. childNodes来判断tagName,如果是input就说明点击了一次,就返回一个false值,让这个内容只能被点击一次。
- 点击之后要自动获取到焦点,输入内容后用正则表达式test判断是否满足条件。如果满足就修改内容并且把原始数据修改,不满足就弹出提示框,并且把刚才修改的内容恢复为原始值。
3.具体的做法(分布讲解,非常容易理解)
- 生成一个表格 tbody部分留空
<table border="1px" width="600px" cellspacing="1">
<thead>
<tr>
<th>名字</th>
<th>年龄</th>
<th>手机号</th>
<th>生日</th>
</tr>
</thead>
<tbody id="tbody">
</tbody>
2.在js里面写入数据
var data=[
{
name:'小唐',
age:20,
phone:'14888888888',
birthday:'2000-02-18'
},
{
name:'小娜',
age:20,
phone:'14888888888',
birthday:'2000-03-17'
},
{
name:'面面',
age:1,
phone:'14888888888',
birthday:'2020-11-15'
}
];
3.让data里面的内容显示在tbody里面去,生成一个表格
var tbody=document.getElementById('tbody');
function setData(myData){
myData.forEach(function(value){
console.log(value);
var tr=document.createElement('tr');
tr.innerHTML='<td>'+value.name+'</td><td>'+value.age+'</td><td>'+value.phone+'</td><td>'+value.birthday+'</td>';
tbody.appendChild(tr);
tr.setAttribute('name','editable');
});
};
setData(data);
这里讲解一下,首先获取到tbody,然后写一个函数setData,用forEach遍历到形参里的内容,生成一个tr,tr里面的innerHTML就写3个td,td里面的内容就写形参里面的各项值,然后在tbody里面创造出tr,注意一个细节,我创造的tr用setAttribute加上了一个name值,方便后面好查找可以编辑的内容。最后调用这个函数,把data参数传递进去,就可以在页面上生成表格了。
4.我给大家演示一下我如何找到各项要修改的表单,并且各项表单的判断方法不一样,需要具体找td表单.
var edii=document.getElementsByName('editable');
console.log(edii);
这里是找到我刚才加入name属性的tr
输出结果如下:
可以看到我刚才创造的3个tr内容。注意用这个dom方法返回的是一个数组,最简单看dom操作是否返回数组可以看getElement后面是否有s.
然后
console.log(edii[0]);
就可以找到一个tr,下面有3个td.
最后
console.log(edii[0].childNodes[0]);
console.log(edii[0].childNodes[1]);
console.log(edii[0].childNodes[2]);
console.log(edii[0].childNodes[3]);
即可输出需要修改的td格,输出结果为:
可以看到是4个不同的内容 ,也是我们需要修改的内容!
5.点击之后的做法
var edi0=document.getElementsByName('editable')[0].childNodes;
var edi1=document.getElementsByName('editable')[1].childNodes;
var edi2=document.getElementsByName('editable')[2].childNodes;
console.log(edi0[0]);
console.log(edi0[1]);
console.log(edi0[2]);
同样的输出:
我相信大家看得懂,这样很容易找到各个要修改的数据!
然后就需要绑定事件了
edi0[0].onclick=function(){
if(this.childNodes[0].tagName=='INPUT'){
return false;
};
var used=edi0[0].innerHTML;
this.innerHTML='';
console.log(this);
var inputs=document.createElement('input');
inputs.value=used;
inputs.type="text";
inputs.style.border="none";
inputs.style.textAlign="center";
inputs.style.fontSize="16px";
this.appendChild(inputs);
inputs.focus();
var reg=/^[\u4E00-\u9FA5\uf900-\ufa2d]{2,4}$/;
that=this;
inputs.onblur=function(){
if(reg.test(inputs.value)){
that.innerHTML='<td>'+inputs.value+'</td>';
data[0].name=inputs.value;
console.log(data[0].name);
}
else{
that.innerHTML='<td>'+used+'</td>';
alert('输入的字数请在2-4位并且是汉字');
}
}
}
首先需要想到一个小细节,如果我们点击了要修改的td格,就会变成一个input输入框,如果再次点击就又生成一个输入框,我们要求只能点击一次,为了防止出错!
这里是
if(this.childNodes[0].tagName=='INPUT'){
return false;
};
如果当前单元格包含了input输入框,我们用tagName来判断,就返回false,就不会发生多次点击出现错误的情况.
然后点击td单元格之后生成input输入框
var used=edi0[0].innerHTML;
this.innerHTML='';
// console.log(this);
var inputs=document.createElement('input');
inputs.value=used;
inputs.type="text";
inputs.style.border="none";
inputs.style.textAlign="center";
inputs.style.fontSize="16px";
this.appendChild(inputs);
inputs.focus();
需要用used保存当前td单元格的原始值,然后清空单元格,然后创造一个input输入框,写入各种css,然后在这个单元格上面创造出输入框,然后获取到这个输入框的焦点。
然后我们需要用正则表达式判断输入的内容是否合理,合理就修改,不合理就提示,如下:
var reg=/^[\u4E00-\u9FA5\uf900-\ufa2d]{2,4}$/;
that=this;
inputs.onblur=function(){
if(reg.test(inputs.value)){
that.innerHTML='<td>'+inputs.value+'</td>';
data[0].name=inputs.value;
console.log(data[0].name);
}
else{
that.innerHTML='<td>'+used+'</td>';
alert('输入的字数请在2-4位并且是汉字');
}
}
注意这里的that指的是当前的单元格,函数里面的this指向的不是单元格而是输入框,我们在外面保存单元格的this,在函数里面就可以调用了。然后当输入框失去焦点,用正则表达式判断合理,合理就会修改当前单元框里面的内容,并且修改data数据里相应的值,不合理就弹出提示框.
其他的各个单元格的操作基本一致,就修改掉正则表达式即可!.
具体的代码如下(有点长,我没有把函数封装,也没有用循环的方法!)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
tr,td,th{
text-align: center;
};
#input{
width: 10px;
}
</style>
</head>
<body>
<table border="1px" width="600px" cellspacing="1">
<thead>
<tr>
<th>名字</th>
<th>年龄</th>
<th>手机号</th>
<th>生日</th>
</tr>
</thead>
<tbody id="tbody">
</tbody>
</table>
<script>
var data=[
{
name:'小唐',
age:20,
phone:'14888888888',
birthday:'2000-02-18'
},
{
name:'小娜',
age:20,
phone:'14888888888',
birthday:'2000-03-17'
},
{
name:'面面',
age:1,
phone:'14888888888',
birthday:'2020-11-15'
}
];
var tbody=document.getElementById('tbody');
function setData(myData){
myData.forEach(function(value){
console.log(value);
var tr=document.createElement('tr');
tr.innerHTML='<td>'+value.name+'</td><td>'+value.age+'</td><td>'+value.phone+'</td><td>'+value.birthday+'</td>';
tbody.appendChild(tr);
tr.setAttribute('name','editable');
});
};
setData(data);
//获取可以编辑的项目
var edi0=document.getElementsByName('editable')[0].childNodes;
var edi1=document.getElementsByName('editable')[1].childNodes;
var edi2=document.getElementsByName('editable')[2].childNodes;
console.log(edi0[0]);
console.log(edi0[1]);
console.log(edi0[2]);
var edii=document.getElementsByName('editable');
console.log(edii);
console.log(edii[0].childNodes[0]);
console.log(edii[0].childNodes[1]);
console.log(edii[0].childNodes[2]);
console.log(edii[0].childNodes[3]);
//edi0的名字
edi0[0].onclick=function(){
if(this.childNodes[0].tagName=='INPUT'){
return false;
};
var used=edi0[0].innerHTML;
this.innerHTML='';
// console.log(this);
var inputs=document.createElement('input');
inputs.value=used;
inputs.type="text";
inputs.style.border="none";
inputs.style.textAlign="center";
inputs.style.fontSize="16px";
this.appendChild(inputs);
inputs.focus();
var reg=/^[\u4E00-\u9FA5\uf900-\ufa2d]{2,4}$/;
that=this;
inputs.onblur=function(){
if(reg.test(inputs.value)){
that.innerHTML='<td>'+inputs.value+'</td>';
data[0].name=inputs.value;
console.log(data[0].name);
}
else{
that.innerHTML='<td>'+used+'</td>';
alert('输入的字数请在2-4位并且是汉字');
}
}
}
//edi0的年龄
edi0[1].onclick=function(){
if(this.childNodes[0].tagName=='INPUT'){
return false;
};
var used=edi0[1].innerHTML;
this.innerHTML='';
console.log(this);
var inputs=document.createElement('input');
inputs.value=used;
inputs.type="text";
inputs.style.border="none";
inputs.style.textAlign="center";
inputs.style.fontSize="16px";
this.appendChild(inputs);
inputs.focus();
var reg=/^(?:[1-9][0-9]?|1[01][0-9]|120)$/;
that=this;
inputs.onblur=function(){
if(reg.test(inputs.value)){
that.innerHTML='<td>'+inputs.value+'</td>';
}
else{
that.innerHTML='<td>'+used+'</td>';
alert('输入的字数请在1-120');
}
}
}
//edi0的手机号
edi0[2].onclick=function(){
if(this.childNodes[0].tagName=='INPUT'){
return false;
};
var used=edi0[2].innerHTML;
this.innerHTML='';
console.log(this);
var inputs=document.createElement('input');
inputs.value=used;
inputs.type="text";
inputs.style.border="none";
inputs.style.textAlign="center";
inputs.style.fontSize="16px";
this.appendChild(inputs);
inputs.focus();
var reg=/^1(3|4|5|7|8)\d{9}$/;
that=this;
inputs.onblur=function(){
if(reg.test(inputs.value)){
that.innerHTML='<td>'+inputs.value+'</td>';
}
else{
that.innerHTML='<td>'+used+'</td>';
alert('输入中国的号码');
}
}
}
//edi0的生日
edi0[3].onclick=function(){
if(this.childNodes[0].tagName=='INPUT'){
return false;
};
var used=edi0[3].innerHTML;
this.innerHTML='';
console.log(this);
var inputs=document.createElement('input');
inputs.value=used;
inputs.type="text";
inputs.style.border="none";
inputs.style.textAlign="center";
inputs.style.fontSize="16px";
this.appendChild(inputs);
inputs.focus();
var reg=/^((19[2-9]\d{1})|(20((0[0-9])|(2[0-1]))))\-((0?[1-9])|(1[0-2]))\-((0?[1-9])|([1-2][0-9])|30|31)$/;
that=this;
inputs.onblur=function(){
if(reg.test(inputs.value)){
that.innerHTML='<td>'+inputs.value+'</td>';
}
else{
that.innerHTML='<td>'+used+'</td>';
alert('请输入1920-2021');
}
}
}
//edi1的名字
edi1[0].onclick=function(){
if(this.childNodes[0].tagName=='INPUT'){
return false;
};
var used=edi1[0].innerHTML;
this.innerHTML='';
console.log(this);
var inputs=document.createElement('input');
inputs.value=used;
inputs.type="text";
inputs.style.border="none";
inputs.style.textAlign="center";
inputs.style.fontSize="16px";
this.appendChild(inputs);
inputs.focus();
var reg=/^[\u4E00-\u9FA5\uf900-\ufa2d]{2,4}$/;
that=this;
inputs.onblur=function(){
if(reg.test(inputs.value)){
that.innerHTML='<td>'+inputs.value+'</td>';
}
else{
that.innerHTML='<td>'+used+'</td>';
alert('输入的字数请在2-4位并且是汉字');
}
}
}
//edi1的年龄
edi1[1].onclick=function(){
if(this.childNodes[0].tagName=='INPUT'){
return false;
};
var used=edi1[1].innerHTML;
this.innerHTML='';
console.log(this);
var inputs=document.createElement('input');
inputs.value=used;
inputs.type="text";
inputs.style.border="none";
inputs.style.textAlign="center";
inputs.style.fontSize="16px";
this.appendChild(inputs);
inputs.focus();
var reg=/^(?:[1-9][0-9]?|1[01][0-9]|120)$/;
that=this;
inputs.onblur=function(){
if(reg.test(inputs.value)){
that.innerHTML='<td>'+inputs.value+'</td>';
}
else{
that.innerHTML='<td>'+used+'</td>';
alert('输入的字数请在1-120');
}
}
}
//edi1的手机号
edi1[2].onclick=function(){
if(this.childNodes[0].tagName=='INPUT'){
return false;
};
var used=edi1[2].innerHTML;
this.innerHTML='';
console.log(this);
var inputs=document.createElement('input');
inputs.value=used;
inputs.type="text";
inputs.style.border="none";
inputs.style.textAlign="center";
inputs.style.fontSize="16px";
this.appendChild(inputs);
inputs.focus();
var reg=/^1(3|4|5|7|8)\d{9}$/;
that=this;
inputs.onblur=function(){
if(reg.test(inputs.value)){
that.innerHTML='<td>'+inputs.value+'</td>';
}
else{
that.innerHTML='<td>'+used+'</td>';
alert('输入中国的号码');
}
}
}
//edi1的生日
edi1[3].onclick=function(){
if(this.childNodes[0].tagName=='INPUT'){
return false;
};
var used=edi1[3].innerHTML;
this.innerHTML='';
console.log(this);
var inputs=document.createElement('input');
inputs.value=used;
inputs.type="text";
inputs.style.border="none";
inputs.style.textAlign="center";
inputs.style.fontSize="16px";
this.appendChild(inputs);
inputs.focus();
var reg=/^((19[2-9]\d{1})|(20((0[0-9])|(2[0-1]))))\-((0?[1-9])|(1[0-2]))\-((0?[1-9])|([1-2][0-9])|30|31)$/;
that=this;
inputs.onblur=function(){
if(reg.test(inputs.value)){
that.innerHTML='<td>'+inputs.value+'</td>';
}
else{
that.innerHTML='<td>'+used+'</td>';
alert('请输入1920-2021');
}
}
}
//edi2
//edi2的名字
edi2[0].onclick=function(){
if(this.childNodes[0].tagName=='INPUT'){
return false;
};
var used=edi2[0].innerHTML;
this.innerHTML='';
console.log(this);
var inputs=document.createElement('input');
inputs.value=used;
inputs.type="text";
inputs.style.border="none";
inputs.style.textAlign="center";
inputs.style.fontSize="16px";
this.appendChild(inputs);
inputs.focus();
var reg=/^[\u4E00-\u9FA5\uf900-\ufa2d]{2,4}$/;
that=this;
inputs.onblur=function(){
if(reg.test(inputs.value)){
that.innerHTML='<td>'+inputs.value+'</td>';
}
else{
that.innerHTML='<td>'+used+'</td>';
alert('输入的字数请在2-4位并且是汉字');
}
}
}
//edi2的年龄
edi2[1].onclick=function(){
if(this.childNodes[0].tagName=='INPUT'){
return false;
};
var used=edi2[1].innerHTML;
this.innerHTML='';
console.log(this);
var inputs=document.createElement('input');
inputs.value=used;
inputs.type="text";
inputs.style.border="none";
inputs.style.textAlign="center";
inputs.style.fontSize="16px";
this.appendChild(inputs);
inputs.focus();
var reg=/^(?:[1-9][0-9]?|1[01][0-9]|120)$/;
that=this;
inputs.onblur=function(){
if(reg.test(inputs.value)){
that.innerHTML='<td>'+inputs.value+'</td>';
}
else{
that.innerHTML='<td>'+used+'</td>';
alert('输入的字数请在1-120');
}
}
}
//edi2的手机号
edi2[2].onclick=function(){
if(this.childNodes[0].tagName=='INPUT'){
return false;
};
var used=edi2[2].innerHTML;
this.innerHTML='';
console.log(this);
var inputs=document.createElement('input');
inputs.value=used;
inputs.type="text";
inputs.style.border="none";
inputs.style.textAlign="center";
inputs.style.fontSize="16px";
this.appendChild(inputs);
inputs.focus();
var reg=/^1(3|4|5|7|8)\d{9}$/;
that=this;
inputs.onblur=function(){
if(reg.test(inputs.value)){
that.innerHTML='<td>'+inputs.value+'</td>';
}
else{
that.innerHTML='<td>'+used+'</td>';
alert('输入中国的号码');
}
}
}
//edi2的生日
edi2[3].onclick=function(){
if(this.childNodes[0].tagName=='INPUT'){
return false;
};
var used=edi2[3].innerHTML;
this.innerHTML='';
console.log(this);
var inputs=document.createElement('input');
inputs.value=used;
inputs.type="text";
inputs.style.border="none";
inputs.style.textAlign="center";
inputs.style.fontSize="16px";
this.appendChild(inputs);
inputs.focus();
var reg=/^((19[2-9]\d{1})|(20((0[0-9])|(2[0-1]))))\-((0?[1-9])|(1[0-2]))\-((0?[1-9])|([1-2][0-9])|30|31)$/;
that=this;
inputs.onblur=function(){
if(reg.test(inputs.value)){
that.innerHTML='<td>'+inputs.value+'</td>';
}
else{
that.innerHTML='<td>'+used+'</td>';
alert('请输入1920-2021');
}
}
}
</script>
</body>
</html>
最后希望各位大佬多提点意见和不足