当前位置: 首页 > article >正文

用 JavaScript 打造交互式表格:添加与删除行功能

前言

在网页开发中,创建交互式表格是很常见的。今天我们通过一个示例,来展示如何使用 HTML、CSS 和 JavaScript 实现一个能够动态添加和删除行的表格,并详细解释其中 JavaScript 部分的代码逻辑。

功能展示

  1. 初始状态:页面加载后,表格已经存在一行数据,包含序号、内容以及一个删除按钮。
  2. 添加行:点击 “添加行” 按钮,表格会新增一行,内容列的数据每次按固定值递增。
  3. 删除行:点击每行中的 “删除” 按钮,对应的行将从表格中移除。
  4. 序号与颜色更新:每次添加或删除行后,表格的序号会重新排序,并且根据行的奇偶性,为行设置不同的背景颜色,以增强可读性。

效果展示

点击删除按钮会删除对应的数据,并且后续的数据继续替补上一条数据的序号,但内容不变,颜色仍然是偶数行

代码部分

HTML结构

这里定义了一个基本的 HTML 页面结构,包含一个具有特定样式的表格。thead部分定义了表头,tbody部分初始有一行数据,并且页面底部有一个用于添加行的按钮。

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title></title>
  <style type="text/css">
    #tablee {
      border-collapse: collapse;
      text-align: center;
    }

    td {
      border-style: solid;
      border-width: 1px;
      padding: 5px;
    }
  </style>
</head>

<body>
  <table id="tablee" cellspacing="" cellpadding="">
    <thead>
      <tr>
        <td>序号</td>
        <td>内容</td>
        <td>操作</td>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>1</td>
        <td>100</td>
        <td><button id="deleteButton">删除</button></td>
      </tr>
    </tbody>
  </table>
  <button id="addButton">添加行</button>

CSS部分

#tablee {
  border-collapse: collapse;
  text-align: center;
}

td {
  border-style: solid;
  border-width: 1px;
  padding: 5px;
}

JS部分

1.变量声明及初始化
  1. addButton:通过getElementById方法获取页面中的 “添加行” 按钮元素,以便后续为其添加点击事件。
  2. tbody:使用querySelector获取表格的tbody元素,后续对表格行的添加、删除操作都将围绕这个元素进行。
  3. data:初始化一个数据变量,用于生成 “内容” 列的数据,初始值为 100。
// 获取添加行按钮,为了添加事件
let addButton = document.getElementById('addButton');
// 获取tbody,为了进行一系列操作(对他的子集)
let tbody = document.querySelector('tbody');
// 声明数据  这是初始化的数据 从100开始
let data = 100;
2.添加行功能
  1. 事件绑定:为addButton添加click事件监听器,当按钮被点击时,执行回调函数。
  2. 创建新行及单元格
    • 使用document.createElement('tr')创建一个新的表格行元素newTr
    • 依次创建三个td单元格,分别用于显示序号(numTd)、内容(contentTd)和操作按钮(operateTd)。
  3. 填充单元格内容
    • 对 “内容” 单元格contentTd,先将data的值增加 100,然后将新值写入contentTdinnerHTML
    • 为 “操作” 单元格operateTd创建一个 “删除” 按钮tdButton,并将按钮添加到该单元格。
  4. 添加新行到表格:将包含三个单元格的newTr行添加到tbody中。
  5. 更新序号和颜色:调用setNumberAndColor函数,对表格的序号和行背景颜色进行更新。
// 给添加按键添加事件
addButton.onclick = function () {
  // 1.创建一个新的tr行
  let newTr = document.createElement('tr');
  // 2.创建第一个单元格
  let numTd = document.createElement('td');
  // 2.1.把第一个td插到Tr里
  newTr.appendChild(numTd)
  // 3.创建第二个单元格
  let contentTd = document.createElement('td');
  // 3.1.data值加100后,重新赋值给data
  data += 100;
  // 3.2.往contentTd中写入data数据
  contentTd.innerHTML = data;
  // 3.3.把contentTd插入到newTr
  newTr.appendChild(contentTd);
  // 4.创建第三个单元格 
  // 并且第三个单元格里只存放按钮
  let operateTd = document.createElement('td');
  // 5.创建删除按钮
  let tdButton = document.createElement('button');
  // 5.1 按钮名字改成删除
  tdButton.innerHTML = '删除'
  // 5.2把删除按钮插回创建的第三个单元格
  operateTd.appendChild(tdButton);
  // 5.3把第三个单元格插到tr行里
  newTr.appendChild(operateTd);
  // 5.4最后把newTr行插入到tbody中
  tbody.appendChild(newTr);
  // 调用一下封装好的函数 (序号和颜色)
  setNumberAndColor();
};
 3.颜色及序号
  1. 获取所有行:使用document.querySelectorAll('tr')获取页面中所有的tr元素,存储在allTr数组中。
  2. 遍历并设置样式和序号
    • 从索引 1 开始遍历allTr数组(跳过表头行)。
    • 根据索引i的奇偶性,为每行设置不同的背景颜色。如果i能被 2 整除,背景颜色设为黄色;否则设为白色。
    • 通过querySelector('td:first-child')获取每行的第一个td单元格,将其内容设置为当前的行索引i,从而实现序号的更新。
function setNumberAndColor() {
  // let setNumber = 1;
  let allTr = document.querySelectorAll('tr'); /*获取所有tr标签 */
  // 遍历获取到的所有tr
  // 从下标1开始,并且小于 < 获取到的所有tr的长度
  for (let i = 1; i < allTr.length; i++) {
    // 判断是否为偶数
    if (i % 2 == 0) {
      // 满足被2整除的 就加一个背景颜色
      allTr[i].style.backgroundColor = 'yellow';
    } else {
      // 否则 就是白色
      allTr[i].style.backgroundColor = 'white';
    }
    // 获取当前tr行 里的第一个td格:用于显示序列号的单元格
    let getShowNumber = allTr[i].querySelector('td:first-child');
    if (getShowNumber) {
      // ↑↑满足条件的话, ↓↓就把序号添加到 获取的tr行里
      getShowNumber.innerHTML = i; // 设置序号
      // 序号增加1,往后递增
      // setNumber++; // 序号递增
    }
  }
}
4.删除行功能
  1. 事件委托:在tbody元素上添加click事件监听器。这样当点击tbody内的任何元素时,都会触发该事件。
  2. 判断点击目标:获取事件的目标元素targetElement,检查其innerHTML是否为 “删除”。如果是,则表示点击了 “删除” 按钮。
  3. 删除对应行:通过parentElement两次获取到按钮所在的tr行元素,然后使用tbody.removeChild(tr)将该行从tbody中移除。
  4. 更新序号和颜色:调用setNumberAndColor函数,确保删除行后表格的序号和背景颜色依然保持正确的显示。
// 删除按钮
// 用的是 事件监听,因为要确定我在页面上 点的是哪一个元素
tbody.addEventListener('click', function (e) {
  let targetElement = e.target
  if (targetElement.innerHTML == '删除') {
    // 获取到当前元素的父级的父级(他爷爷)
    let tr = targetElement.parentElement.parentElement;
    // 从tbody中删除对应的tr
    tbody.removeChild(tr);
    // 调用封装的函数(序号颜色) 
    // 这里调用是因为防止删除白色行时,下面的黄色行自动向上顶,导致邻近的两行都是黄色
    setNumberAndColor();
  }
})

各行换色思路二:利用字符串拼接

(大致思路一致,不过多赘述)

代码展示 

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			#tablee {
				border-collapse: collapse;
				text-align: center;
			}

			td {
				border-style: solid;
				border-width: 1px;
				padding: 5px;
			}
		</style>
	</head>
	<body>
		<table id="tablee" cellspacing="" cellpadding="">
			<thead>
				<tr>
					<td>序号</td>
					<td>内容</td>
					<td>操作</td>
				</tr>
			</thead>
			<tbody>

			</tbody>
		</table>
																		<!-- 这个思路类似于:
																		 一个城市模块化积木,每个区域有需要新添/放置设施(添加行tr)
																		 把积木在一个底座上一个一个拼起来 然后塞到相应的区域(底座:空字符串;积木:被拼接的td;区域:tbody)
																		因为城市的区域很大 不可能每个地方都重新造设施(改变/添加新的数据) 
																		所以用同一个拼好的积木模板(封装好的函数) 往区域里放置(调用函数)
																		但是有时候想对区域里某个地方的模板进行修改时 就需要把新添的内容放到模板上(添加数据后,数据发生改变就重新调用渲染函数往里面传参数)
																		 -->
		<button id="addButton" type="button">添加行</button>
		<script type="text/javascript">
			/* 声明一个数组(开始显示的数据) */
			let data = [100];
			/* 内容格里的值 */
			let content = 100;
			/* 初始化每次点击,添加按钮的初始值 */
			let addNumber=100;
			
			/* 封装渲染函数 */
			function xuanran(data) {
				/* 拼接字符串,为了拼接tr行的字符串 */
				let str = '';
				/* 循环data,循环几次 就拼接几次  */
				for (let i = 1; i < data.length; i++) {
					/* 拼接字符串,将后续拼接的内容添加到str里  */
								/* 用三元去加颜色 */
					str += '<tr style=" background-color:' + (i % 2 == 0 ? 'pink' : '') + ';">' +
								/* 1.拼接第一个单元格(序号) */
						'<td>' + i + '</td>' +
								/* 2.拼接第二个单元格(内容,内容上面已经给了 从100开始) */
						'<td>' + data[i] + '</td>' +
								/* 3.拼接第三个单元格(删除按钮)
								并设置了自定义属性data_index
								并给了一个i的值为下标,用来确定按钮对应的是哪一行*/
						'<td><button data_index="' + i + '">删除</button></td>' +
						'</tr>'
				}
				/* 上面拼接完之后 并不在页面上
					需要往tbody里塞*/
				let getBody = document.querySelector('tbody');
				/* 把拼接好的字符串写入tbody里 */
				getBody.innerHTML = str;
			};
			
			/* 把conten放入data里 */
			data.push(content);
			/* 每次添加一行content都+100 */
			content += 100;
			/* 上面一行数据发生变化了,所以调用渲染函数(传一下新的参) */
			xuanran(data);


			 // 删除按钮的事件监听 
						/* 1.先获取一下tbody */
			let tbody = document.querySelector('tbody');
						/* 2.然后对tbody监听。添加click点击事件监听。
					e是一个事件对象包含了 与该点击事件相关的各种信息 */
			tbody.addEventListener('click', function(e) {
						/* 3.判断点击的是否为删除 
				e.target 是事件对象 e 的一个属性 ,它指向谁被点击了
				通过e.target.innerHTML去获取被点击的文本内容是否满足条件*/
				if (e.target.innerHTML == '删除') {
						/* 4.获取要删除数据的索引 */
					/* getAttribute 是 DOM 元素的一个方法,用于获取指定元素的某个属性的值 */
					/* 通过e.target来确定谁被点了 然后获取它的下标 */
					let getIndex = e.target.getAttribut        e('data_index');
						/* 5.从数组中删除对应的元素 */
					/* 删除获取的getIndex,删除1个元素
					(,逗号前是已经获取到的元素的对应下标,后是要删除的元素个数) */
					data.splice(getIndex, 1);
					/* 因为值变化了 所以重新调用渲染一下,把新参数传进去 */
					xuanran(data);
				}
			});

			// 添加行按钮 
					/* 1.先获取添加按钮 */
			let addDeleteButto = document.getElementById('addButton');
					/* 2.给添加按钮上点击事件监听 */
			addDeleteButto.addEventListener('click', function() {
				/* 每点击一次添加  内容数值都加100,最上面写了初始值 */
				addNumber += 100;
				/* 把每次叠加的值插入到data里 */
				data.push(addNumber);
				/* 因为数变化了 ,所以重新渲染传参 */
				xuanran(data); 
			});
		</script>
	</body>
</html>

区别部分

  • 对于数组中的每一项,拼接一个完整的 <tr> 元素字符串。
    • 背景颜色设置:使用三元运算符 (i % 2 == 0 ? 'pink' : '') 根据当前行的索引 i 的奇偶性来设置背景颜色。如果 i 是偶数,背景颜色为 pink;否则不设置背景颜色。
    • 序号单元格:第一个 <td> 元素显示当前行的序号 i
    • 内容单元格:第二个 <td> 元素显示 data[i] 的值,即当前数组项的数据。
    • 删除按钮单元格:第三个 <td> 元素包含一个 <button> 元素,按钮上设置了自定义属性 data_index,其值为当前行的索引 i,用于后续识别要删除的行。
/* 封装渲染函数 */
			function xuanran(data) {
				/* 拼接字符串,为了拼接tr行的字符串 */
				let str = '';
				/* 循环data,循环几次 就拼接几次  */
				for (let i = 1; i < data.length; i++) {
					/* 拼接字符串,将后续拼接的内容添加到str里  */
								/* 用三元去加颜色 */
					str += '<tr style=" background-color:' + (i % 2 == 0 ? 'pink' : '') + ';">' +
								/* 1.拼接第一个单元格(序号) */
						'<td>' + i + '</td>' +
								/* 2.拼接第二个单元格(内容,内容上面已经给了 从100开始) */
						'<td>' + data[i] + '</td>' +
								/* 3.拼接第三个单元格(删除按钮)
								并设置了自定义属性data_index
								并给了一个i的值为下标,用来确定按钮对应的是哪一行*/
						'<td><button data_index="' + i + '">删除</button></td>' +
						'</tr>'
				}
				/* 上面拼接完之后 并不在页面上
					需要往tbody里塞*/
				let getBody = document.querySelector('tbody');
				/* 把拼接好的字符串写入tbody里 */
				getBody.innerHTML = str;
			};
			


http://www.kler.cn/a/529209.html

相关文章:

  • 全覆盖路径规划-精准细胞覆盖算法
  • 书生大模型实战营3
  • 分层多维度应急管理系统的设计
  • PHP Error处理与优化指南
  • AI学习指南Ollama篇-使用Ollama构建自己的私有化知识库
  • 快速提升网站收录:利用网站内链布局
  • Linux文件类型
  • 台账思维和GIS思维在资产管理中的不同模式
  • 深度学习推理的整数量化:原理与实证评估
  • 知识管理系统推动企业知识创新与人才培养的有效途径分析
  • 【玩转全栈】--创建一个自己的vue项目
  • 海外问卷调查之渠道查,企业经营的指南针
  • C语言指针专题五 -- void和const指针
  • 【力扣】15.三数之和
  • 网络编程套接字(下)
  • CSS 样式化表格:从基础到高级技巧
  • 快速提升网站收录:利用网站FAQ页面
  • 人工智能入门课【手写自注意力机制】
  • 【回溯】目标和 字母大小全排列
  • 云服务器与Docker
  • 分布式事务组件Seata简介与使用,搭配Nacos统一管理服务端和客户端配置
  • 【华为OD-E卷 - 报数游戏 100分(python、java、c++、js、c)】
  • doris:JSON导入数据
  • Games104——引擎工具链基础
  • Python的那些事第八篇:Python中的类与对象
  • MusicFree-开源的第三方音乐在线播放和下载工具, 支持歌单导入[对标落雪音乐]