news 2026/2/16 10:19:08

原生 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/2/1 22:16:18

YOLO推理速度瓶颈分析与GPU优化建议

YOLO推理速度瓶颈分析与GPU优化建议 在智能制造工厂的质检线上&#xff0c;每秒数十帧的高清图像正源源不断地涌向AI系统——任何一次检测延迟都可能导致缺陷产品流入下一环节。面对这种“零容忍”的实时性挑战&#xff0c;YOLO系列模型虽以高速著称&#xff0c;但在实际部署中…

作者头像 李华
网站建设 2026/2/11 3:14:38

基于鲹鱼优化算法的物流配送中心选址附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。 &#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知,完整Matlab代码获取及仿…

作者头像 李华
网站建设 2026/2/13 2:45:50

FLUX.1-dev微调实战:从环境搭建到生成

FLUX.1-dev微调实战&#xff1a;从环境搭建到生成 在AI图像生成领域&#xff0c;模型的“个性化”正成为新的竞争焦点。即便是像FLUX.1-dev这样拥有120亿参数、基于Flow Transformer架构的顶级文生图模型&#xff0c;也难以在开箱即用的情况下完美匹配每一个特定风格或品牌需求…

作者头像 李华
网站建设 2026/2/6 17:03:30

大模型微调超参建议:参考Anything-LLM训练数据统计特征

大模型微调超参建议&#xff1a;参考Anything-LLM训练数据统计特征 在企业知识库、个人文档助手等实际应用场景中&#xff0c;大语言模型&#xff08;LLMs&#xff09;的“能说”不代表“会用”。用户真正关心的是&#xff1a;模型能不能准确理解我上传的PDF技术手册&#xff1…

作者头像 李华
网站建设 2026/1/29 14:21:40

国产AI框架PaddlePaddle安装全攻略:支持GPU的docker安装步骤详解

国产AI框架PaddlePaddle安装全攻略&#xff1a;支持GPU的Docker安装步骤详解 在深度学习项目开发中&#xff0c;最让人头疼的往往不是模型设计本身&#xff0c;而是环境配置——“在我机器上明明能跑”的问题反复上演。尤其当团队成员使用不同操作系统、CUDA版本不一致、显卡驱…

作者头像 李华
网站建设 2026/2/4 19:33:01

北京种一颗牙需要多少钱呢

北京种一颗牙需要多少钱&#xff1f;深度解析种植牙费用构成与选择牙齿缺失不仅影响美观和咀嚼功能&#xff0c;更关乎长期的口腔健康。随着口腔医疗技术的普及&#xff0c;种植牙已成为修复缺牙的主流方案之一。对于许多北京市民而言&#xff0c;最关心的问题莫过于&#xff1…

作者头像 李华