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来设置节点属性。

JS 可编辑表格的实现的更多相关文章

  1. JS 可编辑表格的实现(进阶)

    1.前言 在普通的可编辑表格的基础上,改进可编辑表格.数据来自外部的json(模拟服务端),通过json数据生成可编辑表格.根据实际情况,表格没有新增数据功能.表格的可编辑列,计算的列,每列的数据大小 ...

  2. JS组件系列——表格组件神器:bootstrap table(三:终结篇,最后的干货福利)

    前言:前面介绍了两篇关于bootstrap table的基础用法,这章我们继续来看看它比较常用的一些功能,来个终结篇吧,毛爷爷告诉我们做事要有始有终~~bootstrap table这东西要想所有功能 ...

  3. Jqgrid入门-使用模态对话框编辑表格数据(三)

            Jqgrid是一个强大的表格插件,它提供了多种方式来编辑数据.这三种方式分别是: Cell Editing——只允许修改某一个单元格内容 Inline Editing——允许在jqGr ...

  4. ExtJS4.2学习(七)EditorGrid可编辑表格(转)

    鸣谢地址:http://www.shuyangyang.com.cn/jishuliangongfang/qianduanjishu/2013-11-14/176.html ------------- ...

  5. jQuery实现可编辑表格

    在很多的网页中,这个可编辑表格在许多地方都是非常有用,配合上AJAX技术能够实现很好的用户体验,下面我 们就jQuery来说明一下可编辑表格的实现步骤 首先是HTML代码,非常简单 <!DOCT ...

  6. 实现Easyui 可编辑表格

    一.前端框架使用的easyui框架 二.后端使用的是jfinal 三.效果图 四.html代码 <div id="table_tree" class="easyui ...

  7. 老男孩Day17作业:后台管理平台编辑表格

    一.作业需求: 后台管理平台 ,编辑表格: 1. 非编辑模式: 可对每行进行选择: 反选: 取消选择 2. 编辑模式: 进入编辑模式时如果行被选中,则被选中的行万变为可编辑状态,未选中的不改变 退出编 ...

  8. easyui datagrid可编辑表格使用经验分享

    文章目录 1相关接口方法 2列属性formatter 3编辑器类型 3.1基于my97的编辑器 3.2简单的密码编辑器 3.3动态增加/删除编辑器 4字段的级联操作 4.1combobox的级联操作 ...

  9. jQuery一步一步实现跨浏览器的可编辑表格,支持IE、Firefox、Safari、

    脚 本 之 家 www.jb51.net 脚本云 专题 素材下载 电子书 软件下载 源码下载 服务器常用软件 a5交易 首页 网页制作 脚本专栏 脚本下载 网络编程 数据库 CMS教程 电子书籍 平面 ...

随机推荐

  1. day24--Java集合07

    Java集合07 14.HashMap底层机制 (k,v)是一个Node,实现了Map.Entry<K,V>,查看HashMap的源码可以看到 jdk7.0 的HashMap底层实现[数组 ...

  2. k8s手动扩缩容

    1. 查询deploy副本数,ready数表示副本数 kubectl get deploy 2.通过命令直接扩容或者缩容,--replicas=1表示把my-dep缩容到副本数1,--replicas ...

  3. 页面POST请求302重定向解决方案

    一.在后端Middleware中判断如果是post请求,返回json格式 二.前端全局js中捕获ajax请求进行处理

  4. Linux之搭建FTP服务

    引用:FTP服务器(File Transfer Protocol Server)是在互联网上提供文件存储和访问服务的计算机,它们依照FTP协议提供服务. FTP是File Transfer Proto ...

  5. KingbaseES R6 集群备库网卡down测试案例

    数据库版本: test=# select version(); version ------------------------------------------------------------ ...

  6. CentOS7使用tar方式安装Containerd,配置文件介绍

    主机:centos 7.9 下载 官网GitHub上下载地址:https://github.com/containerd/containerd/releases 问题: 创建容器后,运行的时候报错: ...

  7. kubeoperator升级步骤

    当前kubeoperator版本是3.6.0 官方文档:https://kubeoperator.io/docs/installation/install/ # 离线升级需要提前下载离线安装包,并解压 ...

  8. gin项目部署到服务器并后台启动

    前言 我们写好的gin项目想要部署在服务器上,我们应该怎么做呢,接下来我会详细的讲解一下部署教程. 1.首先我们要有一台虚拟机,虚拟机上安装好go框架. 2.将写好的项目上传到虚拟机上. 3.下载好项 ...

  9. PHP全栈开发:在本机上创建虚拟主机与域名

    如何在windows+wamp环境上进行自己创建的网站的域名访问 step 1 在wamp的安装目录,如C:\wamp64\www\下创建自己的网站目录pe step 2 右键wamp图标,在wamp ...

  10. liunx之expect简介

    导航: 一.expect安装.介绍.使用场景二.expect使用原理三.expect使用语法四.expect使用举例五.expect相关错误处理 - - - - - - - - - 分割线 - - - ...