js实现动态添加删除表格数据的两种方式

目录

1、通过创建节点实现

css代码

html代码

js代码

完整代码

2、通过渲染表格,事件委托实现

css代码

html代码

js代码

完整代码

效果图


1、通过创建节点实现

思路:先把整体的html结构写出来,table表格分为3部分,其中tbody中的内容通过节点创建出来,删除时,找到其祖先元素的节点进行remove(),表单内的各个框的值对应表格的内容。

css代码

<style>.wrapper {display: flex;margin-left: 100px;margin-top: 100px;}.box {width: 300px;height: 400px;/* border: 2px solid red; */margin-left: 50px;}input {height: 40px;width: 200px;margin-bottom: 30px;}button {background-color: #23669a;color: white;width: 50px;height: 30px;border-radius: 5px;outline: none;border: none;margin-left: 50px;}table {border: 1px solid #dbdbdb;border-collapse: collapse;}table tr,th,td {height: 50px;width: 180px;border: 1px solid #dbdbdb;text-align: center;}thead tr {background-color: #f4f4f5;}tbody tr td:nth-child(3) {color: #f54d7b;}</style>

html代码

<div class="wrapper"><div><table><thead><th>姓名</th><th>科目</th><th>成绩</th><th>操作</th></thead><tbody></tbody><tfoot><tr><td colspan="4"> 总分:<span class="total"></span>平均分: <span class="avg"></span></td></tr></tfoot></table></div><div class="box">姓名:<input type="text" placeholder="请输入姓名" class="name"><br>科目:<input type="text" placeholder="请输入科目" class="sub"><br>分数:<input type="text" placeholder="请输入分数" class="score"><br><button>添加</button></div></div>

js代码

 <script>//获取元素const tbody = document.querySelector('tbody')const btn = document.querySelector('button')const name = document.querySelector('.name')const sub = document.querySelector('.sub')const score = document.querySelector('.score')let total = document.querySelector('.total')let avg = document.querySelector('.avg')//给按钮添加点击事件btn.addEventListener('click', function () {//创建元素const tr = document.createElement('tr')const td1 = document.createElement('td')const td2 = document.createElement('td')const td3 = document.createElement('td')const td4 = document.createElement('td')if(name.value===''||sub.value===''||score.value===''){alert('姓名,科目,成绩不能为空')}else{td1.innerHTML = name.valuetd2.innerHTML = sub.valuetd3.innerHTML = score.valuetd4.innerHTML = '<a href="javascript:;">删除</a>'tr.appendChild(td1)tr.appendChild(td2)tr.appendChild(td3)tr.appendChild(td4)tbody.appendChild(tr)name.value = ''sub.value = ''score.value = ''}let three1 = document.querySelectorAll('tbody tr td:nth-child(3)')let sum = 0for (let j = 0; j < three1.length; j++) {sum += (three1[j].innerHTML - 0)}//总分total.innerHTML = `${sum}`//平均值avg.innerHTML = `${sum / three1.length}`//给创建的a添加删除的点击事件let as = document.querySelectorAll('a')for (let i = 0; i < as.length; i++) {as[i].addEventListener('click', function () {//    tbody.removeChild(this.parentNode.parentNode)sum -= (three1[i].innerHTML - 0)this.parentNode.parentNode.remove()total.innerHTML = `${sum}`// total.innerHTML = `${sum - (three1[i].innerHTML - 0)}`let three = document.querySelectorAll('tbody tr td:nth-child(3)')avg.innerHTML = `${(sum / three.length).toFixed(2) === 'NaN' ? 0 : (sum / three.length).toFixed(2)}`})}})</script>

完整代码

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.wrapper {display: flex;margin-left: 100px;margin-top: 100px;}.box {width: 300px;height: 400px;/* border: 2px solid red; */margin-left: 50px;}input {height: 40px;width: 200px;margin-bottom: 30px;}button {background-color: #23669a;color: white;width: 50px;height: 30px;border-radius: 5px;outline: none;border: none;margin-left: 50px;}table {border: 1px solid #dbdbdb;border-collapse: collapse;}table tr,th,td {height: 50px;width: 180px;border: 1px solid #dbdbdb;text-align: center;}thead tr {background-color: #f4f4f5;}tbody tr td:nth-child(3) {color: #f54d7b;}</style>
</head><body><div class="wrapper"><div><table><thead><th>姓名</th><th>科目</th><th>成绩</th><th>操作</th></thead><tbody></tbody><tfoot><tr><td colspan="4"> 总分:<span class="total"></span>平均分: <span class="avg"></span></td></tr></tfoot></table></div><div class="box">姓名:<input type="text" placeholder="请输入姓名" class="name"><br>科目:<input type="text" placeholder="请输入科目" class="sub"><br>分数:<input type="text" placeholder="请输入分数" class="score"><br><button>添加</button></div></div><script>//获取元素const tbody = document.querySelector('tbody')const btn = document.querySelector('button')const name = document.querySelector('.name')const sub = document.querySelector('.sub')const score = document.querySelector('.score')let total = document.querySelector('.total')let avg = document.querySelector('.avg')//给按钮添加点击事件btn.addEventListener('click', function () {//创建元素const tr = document.createElement('tr')const td1 = document.createElement('td')const td2 = document.createElement('td')const td3 = document.createElement('td')const td4 = document.createElement('td')if(name.value===''||sub.value===''||score.value===''){alert('姓名,科目,成绩不能为空')}else{td1.innerHTML = name.valuetd2.innerHTML = sub.valuetd3.innerHTML = score.valuetd4.innerHTML = '<a href="javascript:;">删除</a>'tr.appendChild(td1)tr.appendChild(td2)tr.appendChild(td3)tr.appendChild(td4)tbody.appendChild(tr)name.value = ''sub.value = ''score.value = ''}let three1 = document.querySelectorAll('tbody tr td:nth-child(3)')let sum = 0for (let j = 0; j < three1.length; j++) {sum += (three1[j].innerHTML - 0)}//总分total.innerHTML = `${sum}`//平均值avg.innerHTML = `${sum / three1.length}`//给创建的a添加删除的点击事件let as = document.querySelectorAll('a')for (let i = 0; i < as.length; i++) {as[i].addEventListener('click', function () {//    tbody.removeChild(this.parentNode.parentNode)sum -= (three1[i].innerHTML - 0)this.parentNode.parentNode.remove()total.innerHTML = `${sum}`// total.innerHTML = `${sum - (three1[i].innerHTML - 0)}`let three = document.querySelectorAll('tbody tr td:nth-child(3)')avg.innerHTML = `${(sum / three.length).toFixed(2) === 'NaN' ? 0 : (sum / three.length).toFixed(2)}`})}})</script></body></html>

2、通过渲染表格,事件委托实现

思路:先把整体的效果图写出来,再通过js渲染到页面上,每次添加一组数据就相当于给数组添加数据,删除事件用事件委托,给祖先元素绑定事件,子元素触发事件会冒泡到祖先元素。

css代码

.score-case {width: 1000px;margin: 50px auto;display: flex;
}
.score-case .table {flex: 4;
}
.score-case .table table {width: 100%;border-spacing: 0;border-top: 1px solid #ccc;border-left: 1px solid #ccc;
}
.score-case .table table th {background: #f5f5f5;
}
.score-case .table table tr:hover td {background: #f5f5f5;
}
.score-case .table table td,
.score-case .table table th {border-bottom: 1px solid #ccc;border-right: 1px solid #ccc;text-align: center;padding: 10px;
}
.score-case .table table td.red,
.score-case .table table th.red {color: red;
}
.score-case .table .none {height: 100px;line-height: 100px;color: #999;
}
.score-case .form {flex: 1;padding: 20px;
}
.score-case .form .form-item {display: flex;margin-bottom: 20px;align-items: center;
}
.score-case .form .form-item .label {width: 60px;text-align: right;font-size: 14px;
}
.score-case .form .form-item .input {flex: 1;
}
.score-case .form .form-item input,
.score-case .form .form-item select {appearance: none;outline: none;border: 1px solid #ccc;width: 200px;height: 40px;box-sizing: border-box;padding: 10px;color: #666;
}
.score-case .form .form-item input::placeholder {color: #666;
}
.score-case .form .form-item .cancel,
.score-case .form .form-item .submit {appearance: none;outline: none;border: 1px solid #ccc;border-radius: 4px;padding: 4px 10px;margin-right: 10px;font-size: 12px;background: #ccc;
}
.score-case .form .form-item .submit {border-color: #069;background: #069;color: #fff;
}

html代码

<div id="app" class="score-case"><div class="table"><table><thead><tr><th>姓名</th><th>科目</th><th>成绩</th><th>操作</th></tr></thead><tbody><!-- <tr><td>1</td><td>语文</td><td class="red">46</td><td><a href="#">删除</a></td></tr> --></tbody><tfoot><tr><td colspan="5"><span class="total">总分:246</span><span style="margin-left: 50px" class="average">平均分:79</span></td></tr></tfoot></table></div><div class="form"><div class="form-item"><div class="label">姓名:</div><div class="input"><input type="text" placeholder="请输入姓名" class="username" /></div></div><div class="form-item"><div class="label">科目:</div><div class="input"><input type="text" placeholder="请输入科目" class="subject" /></div></div><div class="form-item"><div class="label">分数:</div><div class="input"><input type="text" placeholder="请输入分数" class="score" /></div></div><div class="form-item"><div class="label"></div><div class="input"><button class="submit">添加</button></div></div></div></div>

js代码

<script>const list = [{uname: '张三',subject: '语文',score: 20,},{uname: '李四',subject: '数学',score: 20,},{uname: '王五',subject: '英文',score: 20,},]// 1 基于数据渲染页面function render() {let str = ''let sum = 0for (let i = 0; i < list.length; i++) {sum += list[i].scorestr += `<tr><td>${list[i].uname}</td><td>${list[i].subject}</td><td class="red">${list[i].score}</td><td><a href="#" data-id=${i}>删除</a></td></tr>`}document.querySelector('.score-case  tbody').innerHTML = str// 计算总分 平均分 渲染到页面document.querySelector('.total').innerHTML = `总分:${sum}`document.querySelector('.average').innerHTML = `平均分:${(sum / list.length).toFixed(2) === 'NaN'? 0: (sum / list.length).toFixed(2)}`}render()// 2 添加业务const submit = document.querySelector('.submit')submit.addEventListener('click', function () {const uname = document.querySelector('.username')const subject = document.querySelector('.subject')const score = document.querySelector('.score')const uname_v = uname.value.trim()const subject_v = subject.value.trim()const score_v = +score.value.trim()if (!uname_v || !subject_v || !score_v) {alert('姓名、科目 或分数都不能为空 ')return}list.push({uname: uname_v,subject: subject_v,score: score_v,})//  重新渲染render()// 清空文本框uname.value = ''subject.value = ''score.value = ''})//  3 删除document.querySelector('tbody').addEventListener('click', function (e) {console.log(e.target.dataset.id)//  把数组中对应的数据删除list.splice(e.target.dataset.id, 1)// 重新渲染render()})</script>

完整代码

<!DOCTYPE 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" /><link rel="stylesheet" href="./styles/index.css" /><title>Document</title></head><body><div id="app" class="score-case"><div class="table"><table><thead><tr><th>姓名</th><th>科目</th><th>成绩</th><th>操作</th></tr></thead><tbody><!-- <tr><td>1</td><td>语文</td><td class="red">46</td><td><a href="#">删除</a></td></tr> --></tbody><tfoot><tr><td colspan="5"><span class="total">总分:246</span><span style="margin-left: 50px" class="average">平均分:79</span></td></tr></tfoot></table></div><div class="form"><div class="form-item"><div class="label">姓名:</div><div class="input"><input type="text" placeholder="请输入姓名" class="username" /></div></div><div class="form-item"><div class="label">科目:</div><div class="input"><input type="text" placeholder="请输入科目" class="subject" /></div></div><div class="form-item"><div class="label">分数:</div><div class="input"><input type="text" placeholder="请输入分数" class="score" /></div></div><div class="form-item"><div class="label"></div><div class="input"><button class="submit">添加</button></div></div></div></div><script>const list = [{uname: '张三',subject: '语文',score: 20,},{uname: '李四',subject: '数学',score: 20,},{uname: '王五',subject: '英文',score: 20,},]// 1 基于数据渲染页面function render() {let str = ''let sum = 0for (let i = 0; i < list.length; i++) {sum += list[i].scorestr += `<tr><td>${list[i].uname}</td><td>${list[i].subject}</td><td class="red">${list[i].score}</td><td><a href="#" data-id=${i}>删除</a></td></tr>`}document.querySelector('.score-case  tbody').innerHTML = str// 计算总分 平均分 渲染到页面document.querySelector('.total').innerHTML = `总分:${sum}`document.querySelector('.average').innerHTML = `平均分:${(sum / list.length).toFixed(2) === 'NaN'? 0: (sum / list.length).toFixed(2)}`}render()// 2 添加业务const submit = document.querySelector('.submit')submit.addEventListener('click', function () {const uname = document.querySelector('.username')const subject = document.querySelector('.subject')const score = document.querySelector('.score')const uname_v = uname.value.trim()const subject_v = subject.value.trim()const score_v = +score.value.trim()if (!uname_v || !subject_v || !score_v) {alert('姓名、科目 或分数都不能为空 ')return}list.push({uname: uname_v,subject: subject_v,score: score_v,})//  重新渲染render()// 清空文本框uname.value = ''subject.value = ''score.value = ''})//  3 删除document.querySelector('tbody').addEventListener('click', function (e) {console.log(e.target.dataset.id)//  把数组中对应的数据删除list.splice(e.target.dataset.id, 1)// 重新渲染render()})</script></body>
</html>

效果图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/198602.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HNU-电路与电子学-2021期末A卷(不含解析)

【写在前面】 电路与电子学好像是从2020级开设的课程&#xff0c;故实际上目前只有2020与2021两个年级考过期末考试。 本份卷子的参考性很高&#xff0c;这是2020级的期末考卷。题目都是很典型的&#xff0c;每一道题都值得仔细研究透。 特别注意&#xff1a;看得懂答案跟写得…

逆水行舟!浅谈24届双非本科秋招

逆水行舟&#xff01;浅谈24届双非本科的秋招 逆水行舟&#xff01;浅谈24届双非本科的秋招0、背景 -- 写下本文的初衷1、实习 -- 秋招的预备战役1.1 科大讯飞1.2 三七互娱 2、秋招 -- 一场没有硝烟的战争3、总结 -- 做好自己想做的事情 0、背景 – 写下本文的初衷 如题&#…

常用汇编指令集

寄存器 如上是OD展示的寄存器&#xff0c;逐条说明常用的寄存器和标志位含义&#xff1a; EIP&#xff1a;寄存器指向即将要执行的指令的地址&#xff08;EIP中的地址&#xff0c;就是下一步要执行指令的地址&#xff09; ESP&#xff1a;里面的内容永远指向堆栈的最顶端 EAX&…

一文详解集合竞价,建议收藏!

集合竞价是指对在规定的一段时间内接受买卖申报一次性集中撮合的竞价方式。沪深市场9:15-9:25及14:57-15:00为集合竞价的时间段。集合竞价的所有交易以同一个价格成交。集合竞价的成交价确定原则是&#xff1a; 1、可实现最大成交量的价格&#xff1b; 2、高于该价格的买入申…

mac苹果笔记本电脑如何强力删除卸载app软件?

苹果电脑怎样删除app&#xff1f;不是把app移到废纸篓就行了吗&#xff0c;十分简单呢&#xff01; 其实不然&#xff0c;因为在Mac电脑上&#xff0c;删除应用程序只是删除了应用程序的主要组件。大多数时候&#xff0c;系统会有一个相当长的目录&#xff0c;包含所有与应用程…

Java三种代理模式:静态代理、动态代理和CGLIB代理

Java三种代理模式&#xff1a;静态代理、动态代理和CGLIB代理 代理模式 代理模式是23种设计模式种的一种。代理模式是一种结构型设计模式&#xff0c;它允许为其他对象提供一个替代品或占位符&#xff0c;以控制对这个对象的访问。代理模式可以在不修改被代理对象的基础上&am…

C语言之多重循环

目录 二重循环 用break语句强制结束循环 显示图形 绘制等腰直角三角形 多重循环 continue语句 将循环语句的循环体作为循环语句&#xff0c;就可以进行二重、三重循环。这样的循环称为多重循环。 我们先来了解二重循环 二重循环 在之前我们学习到的循环中的程序都比较简…

Java---异常

文章目录 1. 异常概述2. try...catch3. Throwable成员方法4. 编译时异常和运行时异常区别5. 异常处理之throws6. 自定义异常7. throws和throw的区别 1. 异常概述 1. 异常&#xff1a;就是程序中出现了不正常的情况。 2. Error&#xff1a;严重问题&#xff0c;不需要处理。Exce…

【带头学C++】----- 九、类和对象 ---- 9.4 拷贝构造函数、赋值

目录 9.4 拷贝构造函数、赋值 9.4.1 定义拷贝构造函数 9.4.2 拷贝构造和无参构造、有参构造的关系 9.4.3 拷贝构造的几种调用形式 1、旧对象给新对象初始化&#xff0c;调用拷贝构造 2、给对象取别名不会调用拷贝构造 3、普通对象作为函数参数&#xff0c;调用函数时会发…

STM32-GPIO编程

一、GPIO 1.1 基本概念 GPIO&#xff08;General-purpose input/output&#xff09;通用输入输出接口 --GP 通用 --I input输入 --o output输出 通用输入输出接口GPIO是嵌入式系统、单片机开发过程中最常用的接口&#xff0c;用户可以通过编程灵活的对接口进行控制&#xff0c;…

ArcGIS提取DEM中的山脉范围

已知数据&#xff1a;DEM文件ASTGTM_N00E118E.img 使用软件&#xff1a;ArcMap 要求&#xff1a;对数据进行操作&#xff0c;提取数据文件中的山脉范围 下面开始操作&#xff1a; 1、 打开ArcMap将DEM文件ASTGTM_N00E118E.img添加到数据框。 2、 接下来我们打开spatial ana…

虚幻学习笔记8—蓝图操作其他虚幻模块

一、前言 蓝图不仅可以相互之间操作和通信&#xff0c;其他的资源、模块也有操作和通信的方法。文本主要针对蓝图和材质、Niagara、编辑器的通信进行讲解。 二、实现 2.1、蓝图和材质 1&#xff09;首先&#xff0c;在材质蓝图中按住“4鼠标左键”创建一个参数为四维向量的参…

Kafka中的auto-offset-reset配置

Kafka这个服务在启动时会依赖于Zookeeper&#xff0c;Kafka相关的部分数据也会存储在Zookeeper中。如果kafka或者Zookeeper中存在脏数据的话&#xff08;即错误数据&#xff09;&#xff0c;这个时候虽然生产者可以正常生产消息&#xff0c;但是消费者会出现无法正常消费消息的…

【小工具分享】分享一个小工具---可视化数据结构 (初学者建议收藏)

工具链接&#xff1a; 可视化数据结构 这里支持大量数据结构地演示&#xff0c;相当全面&#xff0c;对于初学数据结构或者想更直观感受某个数据结构地实现有很大帮助&#xff0c;能直观的看到该数据结构的增删改查&#xff0c;帮助我们理解某一数据结构的性能~ 下面我演示一下…

揭秘MQTT:为何它是物联网的首选协议?

文章目录 MQTT 协议简介概览MQTT 与其他协议对比MQTT vs HTTPMQTT vs XMPP 为什么 MQTT 是适用于物联网的最佳协议&#xff1f;轻量高效&#xff0c;节省带宽可靠的消息传递海量连接支持安全的双向通信在线状态感知 MQTT 5.0 与 3.1.1MQTT 服务器MQTT 客户端 MQTT 协议简介 概…

设计模式之代理模式(1)

目录 概述定义应用场景主要角色类图 详述基本代码应用实例符合的设计原则 总结 概述 定义 代理模式是一种结构型设计模式&#xff0c;它允许通过一个代理对象来控制对原始对象的访问。代理对象可以在不改变原始对象的情况下&#xff0c;增加一些额外的功能&#xff0c;例如权限…

如何做好一个软件开发项目经理?

要成为一名优秀的软件开发项目经理&#xff0c;需要具备一定的技术知识和管理能力。下面是学习和发展软件开发项目经理职业所需的关键能力和工作内容。 首先&#xff0c;作为软件开发项目经理&#xff0c;你需要具备扎实的软件开发知识和技能。这包括熟悉常用的编程语言、开发框…

Python教程75:textwrap模块 — 文本自动换行与填充

TextWrap模块是一个Python模块&#xff0c;它提供了一些函数和方法来处理文本字符串的包装和填充。这个模块的主要功能是将一个长字符串根据指定的宽度分成多行&#xff0c;可以用于格式化文本输出&#xff0c;使其在指定的行数内完成显示。这个过程通常用于控制文本在终端、文…

面向注解编程—Spring 注解看这一篇就够了

面向注解编程—Spring 注解大全之IOC篇 Spring的一个核心功能是IOC&#xff0c;就是将Bean初始化加载到容器中&#xff0c;调用的时候直接注入即可&#xff0c;使用注解可以大大提高了开发效率&#xff01;。 Bean英文意为 豆子 理解起来就是豆荚里的豌豆&#xff0c;豆荚就是…

.Net core 6.0 升8.0

1 Update Visual Studio 2 3 用Nutget 更新不同套件版本 更新后结果如下&#xff1a;