news 2026/6/22 23:50:05

原生 JS 实现动态表格增删与隔行变色:从原理到实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
原生 JS 实现动态表格增删与隔行变色:从原理到实战

在前端开发中,动态表格是一个非常基础且高频的需求,比如后台管理系统的列表操作、数据展示页面的行管理等。本文将带大家从零开始,使用原生 JavaScript实现一个支持行添加、行删除、隔行变色的动态表格,全程不依赖任何框架,深入理解 DOM 操作与事件处理的核心逻辑。

一、需求分析

我们需要实现的动态表格具备以下功能:

  1. 点击 “按钮” 新增一行数据,序号自动递增,数字以 100 为步长累加;
  2. 点击每行的 “删除” 按钮,移除当前行;
  3. 表格自动实现隔行变色效果,且删除行后样式自动重新校准;
  4. 全程使用原生 DOM 操作,不拼接 HTML 字符串,保证代码安全性与可维护性。

二、技术选型与核心原理

1. 技术选型

  • HTML:搭建表格的基础结构,使用<thead>定义表头,<tbody>承载动态行;
  • CSS:定义隔行变色的样式类,通过类名的添加 / 移除实现样式切换;
  • 原生 JavaScript
    • DOM 创建:document.createElement()动态生成行、单元格、按钮;
    • DOM 操作:appendChild()实现节点的层级挂载;
    • 事件委托:利用事件冒泡机制,给<tbody>绑定点击事件,处理删除逻辑;
    • 样式控制:classList.add()/classList.remove()操作元素类名。

2. 核心原理

  • 动态创建 DOM 节点:不使用innerHTML拼接 HTML,而是通过createElement创建<tr><td><button>等节点,再通过appendChild挂载到父节点上,避免 XSS 风险;
  • 事件委托:删除按钮是动态生成的,无法直接绑定事件,因此给父元素<tbody>绑定点击事件,通过事件对象e.target判断点击的是否为删除按钮,实现动态元素的事件处理;
  • 样式重绘:每次新增或删除行后,重新遍历所有行,根据行的索引重新计算并设置隔行变色样式,保证样式始终正确。

三、完整代码实现

1. HTML 结构

html

预览

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>原生JS动态表格</title> <style> table { border-collapse: collapse; margin-top: 10px; width: 400px; } th, td { border: 1px solid #333; padding: 8px 12px; text-align: center; } .blue-bg { background-color: #cce5ff; } button { padding: 4px 8px; cursor: pointer; } </style> </head> <body> <button onclick="selectAll()">新增行</button> <table class="student"> <thead> <tr> <th>序号</th> <th>数字</th> <th>操作</th> </tr> </thead> <tbody> <!-- 动态行将插入这里 --> </tbody> </table> <script> // 初始化序号与数字 let currentIndex = 0; let num = 100; /** * 新增行函数 */ function selectAll() { // 1. 获取tbody容器 const tbody = document.querySelector('tbody'); // 2. 创建tr行节点 const tr = document.createElement('tr'); // 3. 创建序号单元格 const tdIndex = document.createElement('td'); tdIndex.textContent = currentIndex + 1; tr.appendChild(tdIndex); // 4. 创建数字单元格 const tdNum = document.createElement('td'); num += 100; tdNum.textContent = num; tr.appendChild(tdNum); // 5. 创建操作单元格(包含删除按钮) const tdWork = document.createElement('td'); const delBtn = document.createElement('button'); delBtn.textContent = '删除'; tdWork.appendChild(delBtn); tr.appendChild(tdWork); // 6. 将行添加到tbody tbody.appendChild(tr); // 7. 更新序号 currentIndex++; // 8. 重新渲染隔行变色 renderRowStyle(); } /** * 事件委托 - 处理删除逻辑 */ document.querySelector('.student tbody').addEventListener('click', function(e) { // 判断点击的是否为删除按钮 if (e.target.tagName === 'BUTTON' && e.target.textContent === '删除') { // 获取当前行并移除 const targetTr = e.target.parentElement.parentElement; targetTr.remove(); // 重新渲染隔行变色 renderRowStyle(); } }); /** * 渲染隔行变色样式 */ function renderRowStyle() { // 获取所有行 const trList = document.querySelectorAll('tbody tr'); // 遍历所有行,重置样式并重新设置 for (let i = 0; i < trList.length; i++) { trList[i].classList.remove('blue-bg'); // 偶数行(索引+1为偶数)添加蓝色背景 if ((i + 1) % 2 === 0) { trList[i].classList.add('blue-bg'); } } } </script> </body> </html>

2. 代码分模块解析

(1)HTML 与 CSS 部分
  • HTML 结构:使用<table>标签搭建表格,<thead>定义表头的 “序号、数字、操作” 三列,<tbody>用于承载动态生成的行;
  • CSS 样式:
    • border-collapse: collapse合并表格边框,让表格更美观;
    • .blue-bg类定义隔行变色的背景色;
    • 给按钮、单元格添加内边距和居中样式,提升用户体验。
(2)JavaScript 部分
  1. 初始化变量

    javascript

    运行

    let currentIndex = 0; // 记录当前序号 let num = 100; // 记录初始数字

    两个变量分别用于控制新增行的序号递增和数字累加。

  2. 新增行函数selectAll()

    • 步骤 1:获取<tbody>容器,作为动态行的父节点;
    • 步骤 2:通过document.createElement()依次创建<tr>行、<td>单元格、<button>删除按钮;
    • 步骤 3:使用textContent设置单元格和按钮的文本内容,数字以 100 为步长累加;
    • 步骤 4:通过appendChild()将子节点依次挂载到父节点上,形成tbody → tr → td的层级结构;
    • 步骤 5:调用renderRowStyle()函数,重新渲染隔行变色样式。
  3. 事件委托实现删除功能

    javascript

    运行

    document.querySelector('.student tbody').addEventListener('click', function(e) { if (e.target.tagName === 'BUTTON' && e.target.textContent === '删除') { const targetTr = e.target.parentElement.parentElement; targetTr.remove(); renderRowStyle(); } });
    • 核心逻辑:利用事件冒泡,点击删除按钮时,事件会冒泡到<tbody>上;
    • 通过e.target判断触发事件的元素是否为删除按钮;
    • 通过parentElement向上查找,获取当前行<tr>并调用remove()方法移除;
    • 移除后调用renderRowStyle()重新校准样式。
  4. 隔行变色函数renderRowStyle()

    javascript

    运行

    function renderRowStyle() { const trList = document.querySelectorAll('tbody tr'); for (let i = 0; i < trList.length; i++) { trList[i].classList.remove('blue-bg'); if ((i + 1) % 2 === 0) { trList[i].classList.add('blue-bg'); } } }
    • 遍历所有行,先移除所有行的.blue-bg类,避免样式残留;
    • 判断行的索引i+1是否为偶数,若是则添加.blue-bg类,实现隔行变色;
    • 每次新增或删除行后都调用该函数,保证样式始终正确。

四、功能测试与优化点

1. 功能测试

  • 新增行:点击 “新增行” 按钮,表格会新增一行,序号依次为 1、2、3...,数字依次为 200、300、400...,偶数行自动显示蓝色背景;
  • 删除行:点击某行的 “删除” 按钮,该行会被移除,剩余行的隔行变色样式会自动重新计算,保持正确;
  • 样式稳定性:无论新增多少行、删除任意行,隔行变色的效果始终稳定,不会出现错乱。

2. 优化点

  • 序号优化:当前代码中currentIndex在删除行后不会重置,若需要删除行后序号重新连续,可在renderRowStyle()函数中遍历行并重新设置序号;
  • 数据持久化:可将表格数据存储在数组中,新增行时向数组添加数据,删除行时从数组移除数据,实现 “数据驱动视图”;
  • 空表格提示:当表格没有行时,可在<tbody>中添加 “暂无数据” 的提示行,提升用户体验。

五、总结与拓展

本文通过原生 JavaScript 实现了动态表格的增删与隔行变色,核心是掌握DOM 动态创建事件委托样式重绘这三个知识点。这些知识点是前端开发的基础,也是学习 Vue、React 等框架的前置条件 —— 框架的底层原理正是基于这些原生 API 封装而来。

拓展方向

  • 实现表格数据的本地存储(localStorage),刷新页面后数据不丢失;
  • 添加行编辑功能,点击单元格可修改内容;
  • 实现表格排序功能,点击表头可按序号或数字升序 / 降序排列。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/23 10:53:40

Dify在边缘计算场景下部署的可行性评估

Dify在边缘计算场景下部署的可行性评估 在智能制造车间&#xff0c;一位维修工程师正对着一台故障设备束手无策。他拿起手持终端&#xff0c;用语音提问&#xff1a;“XX型伺服电机报过热警报&#xff0c;可能原因有哪些&#xff1f;”不到两秒&#xff0c;本地AI助手便返回了结…

作者头像 李华
网站建设 2026/6/23 11:37:30

LobeChat能否对接Airtable?轻量级数据库联动方案

LobeChat能否对接Airtable&#xff1f;轻量级数据库联动方案 在智能助手逐渐从“能说会道”走向“能做实事”的今天&#xff0c;一个关键问题浮出水面&#xff1a;如何让AI不只是复述知识&#xff0c;而是真正介入业务流程、操作真实数据&#xff1f;比如&#xff0c;销售经理随…

作者头像 李华
网站建设 2026/6/23 0:22:02

LobeChat能否实现AI故事续写?创意写作激发灵感

LobeChat能否实现AI故事续写&#xff1f;创意写作激发灵感 在数字创作的浪潮中&#xff0c;越来越多的写作者开始面临一个共同困境&#xff1a;灵感枯竭、文风断层、设定空洞。即便是经验丰富的作家&#xff0c;在面对长篇小说或复杂世界观构建时&#xff0c;也常常需要反复推敲…

作者头像 李华
网站建设 2026/6/23 16:51:02

AI知识科普丨什么是 ModelOps?

ModelOps 是 AI Engineering 的核心&#xff0c;专注于人工智能&#xff08;AI&#xff09;、决策模型、深度分析的端到端治理与生命周期管理。 在构建好 AI 基础设施并配置好学习框架和推理引擎后&#xff0c;用户可以自行训练并验证模型&#xff0c;然后通过模型仓库发布模型…

作者头像 李华
网站建设 2026/6/23 17:47:13

Windows 10下Anaconda安装OpenCV指南

Windows 10下Miniconda与OpenCV环境搭建实战指南 在做计算机视觉项目时&#xff0c;最怕的不是算法写不出来&#xff0c;而是环境装不上。明明代码没问题&#xff0c;一跑就报 ImportError: No module named cv2&#xff0c;查了半天才发现是包没装对环境——这种经历相信不少人…

作者头像 李华
网站建设 2026/6/23 17:47:14

LangChain与AutoGPT核心差异与应用场景解析

LangChain与AutoGPT核心差异与应用场景解析 在AI从“能说”走向“能做”的今天&#xff0c;一个根本性问题摆在开发者面前&#xff1a;我们究竟需要一个听话的工具&#xff0c;还是一个会自己想办法的助手&#xff1f; LangChain 和 AutoGPT 正是这一命题下的两种答案。它们都…

作者头像 李华