news 2026/4/23 13:40:32

原生 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/4/23 5:05:44

Qwen-Image-Edit-2509能上手机吗?云端+端侧全解析

Qwen-Image-Edit-2509 能上手机吗&#xff1f;云端与端侧的融合演进 你有没有过这种体验&#xff1a;在地铁上刷社交媒体&#xff0c;突然看到一张照片&#xff0c;脑海里立刻浮现出“如果背景换成海边、加点阳光滤镜&#xff0c;绝对更出片”——可一想到要打开修图软件、手动…

作者头像 李华
网站建设 2026/4/23 14:59:46

LobeChat能否实现API错误诊断?开发者调试加速器

LobeChat能否实现API错误诊断&#xff1f;开发者调试加速器 在AI应用开发的日常中&#xff0c;一个看似简单的问题常常耗费数小时&#xff1a;为什么我的模型API调用失败了&#xff1f; 是密钥错了&#xff1f;URL拼写有误&#xff1f;还是请求体格式不符合文档要求&#xff…

作者头像 李华
网站建设 2026/4/23 13:55:00

【DOA估计】MIMO阵列信号DOA估计,CBF、Capon、MUSIC、LS-ESPRIT、TLS-ESPRIT、ML法、FOCUSS、OMP、CVX、伪逆和SBL结果比较附Matlab代码

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

作者头像 李华
网站建设 2026/4/22 17:48:17

解锁陶瓷出海利润提升密码!外贸ERP管理系统助力订单管理降本增效

中国陶瓷出口历史悠久&#xff0c;工艺陶瓷与日用陶瓷作为传统外贸产业&#xff0c;在国际市场上长期占据重要地位。然而&#xff0c;近年来受贸易保护主义、技术壁垒及成本上升等因素影响&#xff0c;陶瓷出口企业面临订单管理复杂、效率低下、利润压缩等挑战。在此背景下&…

作者头像 李华
网站建设 2026/4/23 13:52:31

社交+AI的化学反应:焦圈儿打造的新型互动模式

在过去的几年里&#xff0c;我们已经习惯了在社交媒体平台上发布状态、分享照片和转发文章——内容是“成品”&#xff0c;互动是喜欢和评论。但与人工智能的对话是不同的&#xff1a;它不是一张图片或一段文字&#xff0c;而是一个来来往往的思考过程。但这种兴奋往往只停留在…

作者头像 李华
网站建设 2026/4/23 11:46:34

LobeChat自托管成本测算:硬件资源需求与预算规划

LobeChat自托管成本测算&#xff1a;硬件资源需求与预算规划 在企业对数据隐私和AI自主可控的需求日益增长的今天&#xff0c;越来越多团队开始将目光从公有云API转向本地化部署的大模型交互系统。尽管像OpenAI这样的服务提供了强大的语言能力&#xff0c;但其调用成本高、数据…

作者头像 李华