可编辑表格
设计思路
-
先通过 CSS+HTML 绘制基础表格样式及布局
-
根据题意:只能修改成绩数据的单元格,给相应 td 设置 name 属性,总分则单独设置 rname 属性,在 js 文件中获取所有需要修改的元素,通过 for 循环遍历给需要修改的单元格添加点击事件。
-
通过点击单元格来更新数据,更新数据需要通过使用 DOMAPI 添加 input 元素来传入新数据。
-
当输入值后根据 if 语句来判断输入值是否符合规定,如果错误则调用错误输入的动画,成功则更新总成绩。
-
更新总成绩通过 DOM 属性来获取每个学生的每门成绩,以及每个学生的总成绩。
-
js 文件中包含获取 html 元素代码,给可编辑单元格添加点击事件,更新单元格,更新总成绩,错误动画。
实现方法
- 在 JS 中通过 getElemByName,getElemByTagName 以及 CSS 选择器 querySelectorAll,parentNode 来获取节点(元素)
- creatElement 创建节点,setAttribute 来设置节点属性
- innerHTML 来改变 HTML 元素文本值
核心代码
html
<div id="tableBox">
<h2 class="title">可编辑表格</h2>
<div class="err">成绩输入有误,请重新输入!</div>
<table class="table">
<thead>
<tr>
<th>学号</th>
<th>姓名</th>
<th>语文</th>
<th>数学</th>
<th>英语</th>
<th>总分</th>
</tr>
</thead>
<tbody>
<tr>
<td>1101</td>
<td>小王</td>
<td name="grade">98</td>
<td name="grade">80</td>
<td name="grade">91</td>
<td rname="allgrade">269</td>
</tr>
<tr>
<td>1102</td>
<td>小曾</td>
<td name="grade">88</td>
<td name="grade">87</td>
<td name="grade">92</td>
<td rname="allgrade">267</td>
</tr>
<tr>
<td>1103</td>
<td>小赵</td>
<td name="grade">75</td>
<td name="grade">90</td>
<td name="grade">86</td>
<td rname="allgrade">251</td>
</tr>
<tr>
<td>1104</td>
<td>小周</td>
<td name="grade">65</td>
<td name="grade">81</td>
<td name="grade">83</td>
<td rname="allgrade">229</td>
</tr>
</tbody>
</table>
</div>
js
//获取HTML中的元素
var grades = document.getElementsByName("grade");
var thetips = document.getElementsByClassName("err")[0];
var trs = document.getElementsByTagName("tr");
// 给单元格添加点击事件
function setCellCilck() {
for (let i = 0; i < grades.length; i++) {
grades[i].onclick = function () {
updateCell(this);
};
}
}
setCellCilck();
// 更新单元格内容
function updateCell(ele) {
if (document.getElementsByClassName("active-input").length == 0) {
var oldhtml = ele.innerHTML;
ele.innerHTML = "";
// 通过DOM API 创建input元素,设置属性,值,方法
var newInput = document.createElement("input");
newInput.setAttribute("class", "active-input");
newInput.value = oldhtml;
newInput.onblur = function () {
if (!Number(this.value) || this.value > 100 || this.value < 0) {
console.log("err");
addAnimate();
thetips.style.display = "block";
return;
} else {
thetips.style.display = "none";
ele.innerHTML = this.value == oldhtml ? oldhtml : this.value;
updateScore();
}
};
newInput.select();
ele.appendChild(newInput);
newInput.focus();
} else {
return;
}
}
// 更新总成绩
// 通过DOM属性来更新总成绩
function updateScore() {
for (let n = 1; n < trs.length; n++) {
var grade01 =
grades[n].parentNode.parentNode.children[n - 1].querySelectorAll(
"td[name]"
);
var grade02 =
grades[n].parentNode.parentNode.children[n - 1].querySelectorAll(
"td[rname]"
);
var sum = 0;
for (let i = 0; i < grade01.length; i++) {
sum += parseFloat(grade01[i].innerHTML);
for (let j = 0; j < grade02.length; j++) {
grade02[j].innerHTML = sum;
}
}
}
}
updateScore();
function addAnimate() {
thetips.className = "err movedown";
}
css
<!-- 错误动画 -->
.err {
display: none;
top: 95px;
width: 160px;
position: absolute;
margin-left: -100px;
left: 50%;
text-align: center;
padding: 15px 18px;
background: rgb(255, 0, 0);
border-radius: 5px;
font-size: 13px;
font-weight: 600;
transition: top 1s;
z-index: -1;
}
.movedown {
top: 95px;
animation: movedown 3s;
}
@keyframes movedown {
0% {
top: 95px;
}
50% {
top: 48px;
}
100% {
top: 95px;
}
}