1、实现效果

用户点击语文,数学,英语部分的单元格,可以实现分数的编辑,总分也会随之变化。先看下效果,如图:

2、设计思路

  • 先通过HTML5+CSS3绘制表格,添加input的样式和err提示动画。
  • 给要修改的数据的单元格添加name属性,给总分那一列的单元格添加rname属性。先获取所有要更改数据的单元格,通过for循环遍历,给他们添加单击事件。
  • 定义一个addAnimate方法,表示单元格输入错误时的动画提示
  • 定义setCellCilck方法,给单元格添加点击事件
  • 定义一个updateCell()方法,里面传入一个ele参数。先要获取旧的数据并保存为oldhtml。然后创建一个input标签,并传入oldhtml。在input标签的聚焦事件中判断输入的input值是否合法,若不合法,则调用addAnimate()方法弹出error标签的错误提示信息,若合法,则直接赋给单元格当前输入的值。
  • 定义一个updateScore方法,用来计算分数。通过class取出每行的分数的值,再取出总成绩的值。每个人总成绩等于每行分数相加。

3、实现源码

table.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>table</title>

</head>

<link rel="stylesheet" href="table.css"> <body>

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

</body>

<script src="table.js"></script>
</html>

table.css

* {
margin: 0;
padding: 0;
--border: 2px solid rgba(121, 121, 121, 1);
}

tableBox {

position: relative;
user-select: none;

}

.table {

margin: 0 auto;

border-spacing: 0;

border-collapse: collapse;

text-align: center;

margin-top: 47px;

z-index: 1;

}

.err {

display: none;

top: 95px;

width: 160px;

position: absolute;

margin-left: -100px;

left: 50%;

text-align: center;

padding: 15px 18px;

background: orange;

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
}

}

.title {

text-align: center;

padding: 8px 0;

}

tr,

td,

th {

border: var(--border)

}

th {

font-weight: 600;

text-align: center;

background-color: rgba(204, 204, 204, 1);

}

td>input {

width: 100px;

height: 45px;

border: none;

font-size: 16px;

}

.table>thead>tr>th,

.table>tbody>tr>td {

width: 100px;

height: 45px;

font-size: 16px;

}

.table>thead>tr {

font-family: '宋体';

}

button {

color: #fff;

background-color: #d9534f;

border-color: #d43f3a;

user-select: none;

border: 1px solid transparent;

border-radius: 4px;

cursor: pointer;

padding: 10px 12px;

font-size: 14px;

text-align: center;

}

table.js:

var stutable = document.getElementsByClassName("table")[0]
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 = '';

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

} } // 更新总成绩

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"

}

4、总结

  • 通过Name,className,parentNode,querySelectorAll等方法来获取节点。
  • 通过createElement来创建节点。
  • 通过setAttribute来设置节点属性。

最新文章

  1. visual studio 2015 搭建python开发环境,python入门到精通[三]
  2. Html5的一些引擎使用感触
  3. tomcat配置及优化
  4. Date类型时间转换
  5. Scrum会议3
  6. api-ms-win-crt-runtime-l1-1-0.dll丢失问题
  7. Project Euler 76:Counting summations
  8. php里面为什么header之前有输出报错 源码分析
  9. Android 图片旋转(使用Matrix.setRotate方法)
  10. 【LeetCode】191. Number of 1 Bits
  11. JMeter打开脚本失败 如何解决?
  12. 以太坊go-ethereum签名部分源码解析
  13. java异常拾遗
  14. 正则表达式,js里的正则应用
  15. Ubuntu 18.04 启用 rc.local 设置开机启动
  16. 有趣的async
  17. 【ARTS】01_03_左耳听风-20181126~1202
  18. PAT 1033 旧键盘打字(20)(20 分)
  19. HDU 4436 str2int (后缀自动机SAM,多串建立)
  20. 结构体的sort【防止遗忘w】

热门文章

  1. 国家都给NISP证书的补贴了!关于NISP考试的政策有哪些?
  2. 你必须学UML之理论篇
  3. [CF1498D] Bananas in a Microwave (DP)
  4. Windows权限维持总结
  5. Python入门系列(七)开发常说的“累”与“对象”
  6. MAC Golang环境搭建
  7. 【全网最全】springboot整合JSR303参数校验与全局异常处理
  8. Elasticsearch:Cluster备份 Snapshot及Restore API
  9. linux软链接的创建、修改和删除
  10. 移动端touch拖动事件和click事件冲突问题解决