传统:就是改html标签的内容(将value值赋值给tr标签中然后添加至tbody中)
数据驱动:所有页面中的学生信息都是由数据渲染的
.添加学生
1.给添加按钮绑定点击事件
2.获取添加的数据(做正则和非空判断)
3.获取tbody标签, 把input的value值渲染到tbody上
先写一个渲染页面的封装函数,方便后面使用。
// 页面的渲染函数
function render(){
tab.innerHTML = '';
data.map((value,index)=> {
tab.innerHTML += `<tr>
<td><span>${value.id}</span></td>
<td>${value.name}</td>
<td>${value.password}</td>
<td>${value.email}</td>
<td>
<button class="btn3">编辑</button>
<button class="btn4" onclick="deleteStu(${value.id})">删除</button>
</td>
</tr>`
})
}
render();
然后在给点击添加按钮添加点击事件,添加之前,做非空判断以及正则判断,全部通过了,才能添加到数据中,然后进行渲染。非空与正则可以封一个函数,这个函数有四个参数,分别是input框,传入的正则,提示框,提示文本.。如果传入的input框中是空的,给出相应的样式,最后在retun一个false终止下面代码执行。如果不是非空,在判断正则是否正确,正确与不正确都给相应的样式,正确就return true,否则return false
function zz(input, reg, t, msg) {
if (!input.value == "") {
if (reg.test(input.value)) {
input.style.border = ".999975px solid green";
t.innerHTML = "验证正确";
t.style.color = "green";
return true;
} else {
input.style.border = ".999975px solid red";
t.innerHTML = msg;
t.style.color = "red";
return false;
}
} else {
input.style.border = ".999975px solid red";
t.innerHTML = "此处不能为空";
t.style.color = "red";
return false;
}
}
btn1.onclick = function () {
if(!zz(inp, /^[\u4e00-\u9fa5]{2,4}$/, t1, "请输入正确的用户名")){
return
}
if(!zz(pasw,/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,16}$/,t2,'请输入6-16包含字母数字的密码')){
return
}
if(!zz(ema,/^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/,t3,'请输入正确的邮箱格式')){
return
}
let name = inp.value;
let password = pasw.value;
let email = ema.value;
data.push({
id:data.length + 1,
name,
password,
email,
})
render();
for(var i = 0;i < input.length;i++){
input[i].value = "";
input[i].style.border = "none";
t[i].innerHTML = '';
};
};
删除
添加行内点击事件,因为不知道当前行数对应的是哪一个删除标签,需要在点击事件内传一个参数,这个参数为每行对应的编号及id。然后在添加点击事件,循环一下数据源,判断数据源中id是否与当前项中的id相等,相等就做删除处理
function deleteStu(id){
// console.log(id)
data.forEach((value,index) => {
console.log(value.id);
if(value.id == id){
data.splice(index,1);
render();
}
})
}
编辑
封装一个函数,在函数内部获取编辑按钮,因为获取的是一个伪数组,把它解构赋值一下,用一个新的数组接一下,在循环当前数组,用事件代理的方式给他父级添加点击事件,给编辑标签添加自定义属性,值是当前点击的id,一个自定义下标,值是当前点击的下标,一个自定义type,做一个判断(三元表达式),当前点击项的一个属性默认为false,值为ok,如果为true的话type值为no,它的文本也是利用这个属性默认做一个判断,默认为false,值为:编辑,为true时,值为:完成,在给当前点击行需要修改内容的地方添加一个input框,默认是display:none, 为true时,display的值为空,然后一个文本框,默认是display:'',为true时display值为none,文本框的文本一直是数据源中的value值,而修改后的input的value值重新赋值给数据源中,从而当我们点击完成时,文本框中又重新渲染了数据源中被修改的数据。
function delBtn(){
let btn3 = document.getElementsByClassName('btn3');
let delBtn1 = [...btn3]
// console.log(delBtn1);
// for(var i = 0; i < btn3.length; i++){
// btn3[i].onclick = function(){
// console.log(this.dataset.id);
// }
// }
delBtn1.forEach(e => {
e.addEventListener('click',function(){
// console.log(this.dataset.id);
const id = this.dataset.id;
let type = this.dataset.type;
const index = this.dataset.index;
let uname1 = document.getElementsByClassName("uname1")[index];
let uname2 = document.getElementsByClassName("uname2")[index];
let uname3 = document.getElementsByClassName("uname3")[index];
data.forEach(value =>{
if(+id === value.id) {
// value.isDel = type === 'ok';
// type !== 'ok' && (value.name = uname1.value);
if(type === 'ok') {
value.isDel = true;
} else {
const item = uname1.value;
value.name = uname1.value;
value.password = uname2.value;
value.email = uname3.value;
value.isDel = false;
}
}
})
render()
})
})
}