设计思路:
在实现可编辑表格基础功能的情况下,做到对其具体功能的模块化,并且将其数据来源于服务端,由JSON格式展示,当在表格上进行编辑时,异步更新JSON文件中的数据。
实现方法:
通过json-server来模拟后台的数据操作,编写具体的json文件,将要渲染的表格数据初始化在json文件中。
在已完成的基础可编辑表格上,通过ajax请求,将json文件中的数据获取,然后再通过js渲染DOM内容,实现初始化表格的生成。
再根据需求,对表格进行功能的添加,将增加,删除,修改的功能,通过函数封装,将其功能绑定到具体的元素中,实现表格的功能需求。
具体功能代码:
1.读取json数据:
// 读取本地json数据
let ajax = new XMLHttpRequest();
ajax.open("get", "data.json");
ajax.send();
ajax.onreadystatechange = function () {
if (ajax.readyState == 4 && ajax.status == 200) {
let alldata = JSON.parse(ajax.responseText);
title_data.push(alldata.t_title);
grade_data.push(alldata.t_grades);
getHtml(); // 生成HTML
}
};
2.渲染DOM完善表格:
let stutable = document.getElementsByClassName("table")[0];
let stutable_title = stutable.getElementsByTagName("thead")[0]
.getElementsByTagName("tr")[0]; // 获取th标题行
let stutable_grade = stutable.getElementsByTagName("tbody")[0]; // 获取tbody
let stu_trs = stutable_grade.getElementsByTagName("tr"); // 获取tbody的tr标签
var title_data = []; // 存放标题数据
var grade_data = []; // 存放成绩数据
let delbtns = document.getElementsByTagName("button");
let addbtns = document.getElementsByTagName("button");
var editcell = document.getElementsByName("editable"); // 可编辑的单元格
var thetips = document.getElementsByClassName("err")[0];
var alltr = document.getElementsByTagName("tr"); // 获取HTML中所有的tr标签
var flag; // 设置是否显示删除栏
// 渲染DOM内容
function getHtml() {
let titlekey, gradekey; // 用于存放对象的key
// 表头
for (item of title_data) {
for (let i = 0; i < item.length; i++) {
titlekey = Object.values(item[i]); // 取出表头数据
let temp_title = `
<th>${titlekey}</th>
`;
stutable_title.insertAdjacentHTML("beforeend", temp_title);
}
}
// 表格内容
for (item of grade_data) {
for (let i = 0; i < item.length; i++) {
gradekey = Object.keys(item[i]);
let temp_grade = `<tr>`;
// console.log(gradekey); // 获取到的key数组
for (let j in gradekey) {
let k = gradekey[j]; // 获取到的key值
// console.log(item[i][k]); // 取出对象中的值
// 判断是否是最后一个键名
if (j == gradekey.length - 1) {
temp_grade += `<td>${item[i][k]}</td></tr>`;
} else {
temp_grade += `<td>${item[i][k]}</td>`;
}
}
stutable_grade.insertAdjacentHTML("beforeend", temp_grade);
}
}
setEditable([2, 3]); // 设置可编辑单元格
flag = true; // 删除栏
if (flag) actionBar(); // 生成操作栏
}
// 添加操作栏
function actionBar() {
let caozuo = document.createElement("th");
caozuo.innerText = "操作";
stutable_title.appendChild(caozuo);
for (let k = 0; k < stu_trs.length; k++) {
let caozuo2 = document.createElement("td");
let btn = document.createElement("button");
btn.innerText = "删除";
caozuo2.appendChild(btn);
stu_trs[k].appendChild(caozuo2);
}
delRow(); // 删除操作
}
// 给单元格添加点击事件
function setCellCilck() {
let scorearr = [30, 9999];
for (let i = 0; i < editcell.length; i++) {
editcell[i].onclick = function () {
updateCell(this, scorearr);
delRow();
};
}
}
3.函数功能封装:
// 更新单元格内容
function updateCell(ele, scorearr) {
let scoreMax = scorearr[ele.cellIndex - 2];
scoreMax = scoreMax || 100;
console.log("当前输入最大值:" + scoreMax);
if (document.getElementsByClassName("active-input").length == 0) {
var oldhtml = ele.innerHTML;
ele.innerHTML = "";
var newInput = document.createElement("input");
newInput.setAttribute("class", "active-input");
newInput.value = oldhtml;
newInput.onblur = function () {
this.value = parseFloat(this.value);
if (this.value < 0 || this.value > scoreMax) {
console.log("err");
addAnimate();
thetips.style.display = "block";
return;
} else {
thetips.style.display = "none";
ele.innerHTML = this.value == oldhtml ? oldhtml : this.value;
/* 映射数据表 */
// 取出当前单元格数据
let ediId = ele.parentNode.children[0].innerHTML; // 获取当前修改的单元格的id
// console.log(ediId);
for (item of grade_data) {
for (let i = 0; i < item.length; i++) {
// 取出数据集的所有键名
let gradekey = Object.keys(item[i]);
// console.log(item[i].id); // 取出数据集的id
// console.log(ele.cellIndex); // 输出当前单元格所在行的列数
if (item[i].id == ediId) {
item[i][gradekey[ele.cellIndex]] = parseFloat(this.value);
}
}
}
console.log("修改后的数据是:", grade_data);
}
};
newInput.select();
ele.appendChild(newInput);
newInput.focus();
} else {
return;
}
}
// 添加动画
function addAnimate() {
thetips.className = "err movedown";
}
// 删除表格行
function delRow() {
for (let i = 0; i < delbtns.length; i++) {
delbtns[i].onclick = function () {
let rowindex = this.parentNode.parentNode.rowIndex; // 获取当前行
let delindex = rowindex - 1;
stutable.deleteRow(rowindex);
/* 映射数据表 */
let ediId = this.parentNode.parentNode.children[0].innerHTML; // 获取当前单元格的id
for (item of grade_data) {
for (let i = 0; i < item.length; i++) {
if (item[i].id == ediId) {
item.splice(delindex, 1);
console.log("删除后的数据是:", grade_data);
}
}
}
};
}
}
总结:
为实现可编辑表格的功能的数据管理,这里采用了json文件读的操作,使得数据能够在不手动编写html文件的情况下,实现表格的初始化正常更新,并且对于html中的各个元素节点,通过原生js的操作,使得每一个节点都能被具体的函数事件绑定,实现了功能渲染,以及动态的添加,与基础版本的编辑表格不同的是,可以灵活的决定表格的初始内容。
但此表格只实现了读取数据的功能,并没有编写出对数据更改,并映射到json文件中的功能。仍然有更改优化的空间。