为什么UNet在医学图像分割上这么强?聊聊它的‘U型’结构与数据困境的完美匹配
2026/6/2 3:58:55
在后台管理系统、表单录入页面等前端开发场景中,表格是数据展示与交互的核心载体,而 “动态新增 / 删除表格行” 是高频且基础的业务需求 —— 小到商品订单明细录入,大到员工信息批量编辑,都离不开这一功能。本文将从业务场景拆解、核心原理剖析、代码优化实现、拓展方案落地四个维度,手把手教你用 jQuery 实现企业级标准的表格行动态增删功能,代码兼顾可读性、可维护性与用户体验,适配新手学习与生产环境直接复用。
我们不仅要实现基础功能,更要贴合实际业务场景的交互逻辑,核心需求如下:
html
预览
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>jQuery 动态增删表格行(企业级方案)</title> <!-- 引入 jQuery 库(优先CDN,兼容本地备用) --> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <script> // 降级处理:CDN加载失败时加载本地jQuery window.jQuery || document.write('<script src="../js/jquery-3.7.1.min.js"><\/script>'); </script> <style> /* 基础样式重置:消除浏览器默认差异 */ * { margin: 0; padding: 0; box-sizing: border-box; } body { padding: 30px; font-family: "Inter", "Microsoft Yahei", sans-serif; background-color: #f8fafc; } /* 表格容器:适配响应式 */ .table-container { width: 90%; max-width: 1000px; margin: 0 auto; } /* 表格样式:企业级视觉规范 */ #myTable { width: 100%; border-collapse: collapse; margin: 20px 0; background-color: #fff; border-radius: 8px; overflow: hidden; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } #myTable th { background-color: #f1f5f9; color: #1e293b; font-weight: 600; padding: 16px; text-align: center; border-bottom: 2px solid #e2e8f0; } #myTable td { padding: 16px; text-align: center; border-bottom: 1px solid #e2e8f0; color: #334155; } #myTable tr:hover { background-color: #f8fafc; transition: background-color 0.2s ease; } /* 空状态提示 */ .empty-tip { height: 80px; line-height: 80px; color: #94a3b8; text-align: center; } /* 新增按钮样式:符合交互规范 */ .add-btn { display: block; width: 160px; height: 44px; line-height: 44px; text-align: center; background-color: #3b82f6; color: #fff; border-radius: 8px; margin: 0 auto 20px; cursor: pointer; border: none; font-size: 15px; transition: all 0.2s ease; } .add-btn:hover { background-color: #2563eb; transform: translateY(-1px); } .add-btn:active { transform: translateY(0); } /* 删除按钮样式 */ .del-btn { padding: 6px 16px; background-color: #ef4444; color: #fff; border: none; border-radius: 6px; cursor: pointer; font-size: 13px; transition: background-color 0.2s ease; } .del-btn:hover { background-color: #dc2626; } /* 响应式适配:移动端优化 */ @media (max-width: 768px) { .table-container { width: 100%; overflow-x: auto; } #myTable { min-width: 600px; } .add-btn { width: 140px; height: 40px; line-height: 40px; } } </style> </head> <body> <div class="table-container"> <!-- 新增按钮 --> <button class="add-btn" id="addTableRow">新增表格行</button> <!-- 表格容器 --> <table id="myTable"> <thead> <tr> <th>序号</th> <th>内容</th> <th>操作</th> </tr> </thead> <tbody id="tableBody"> <!-- 初始行 --> <tr> <td>1</td> <td>默认内容</td> <td><button class="del-btn">删除</button></td> </tr> </tbody> </table> </div> <script> // jQuery 入口函数:确保DOM加载完成 $(function() { // 缓存DOM节点:减少重复选择器查询,提升性能 var $tableBody = $("#tableBody"); var $addBtn = $("#addTableRow"); // 初始化空状态检查 checkEmptyState(); // 1. 新增表格行核心逻辑 $addBtn.on("click", function() { // 获取当前行数,计算新序号 var rowCount = $tableBody.find("tr").length + 1; // 构建新行(模板化,便于后续维护) var newTr = $(` <tr> <td>${rowCount}</td> <td>新增内容</td> <td><button class="del-btn">删除</button></td> </tr> `); // 移除空状态提示(如果存在) $tableBody.find(".empty-tip").remove(); // 追加新行 $tableBody.append(newTr); }); // 2. 删除表格行逻辑(事件委托:兼容动态元素) $tableBody.on("click", ".del-btn", function() { // 确认删除:防止误操作 if (!confirm("确定要删除这一行吗?")) { return; } // 删除当前行 $(this).closest("tr").remove(); // 重新排序序号 resetRowIndex(); // 检查空状态 checkEmptyState(); }); // 工具函数:重置表格行序号 function resetRowIndex() { $tableBody.find("tr").each(function(index) { $(this).find("td:first").text(index + 1); }); } // 工具函数:检查并处理表格空状态 function checkEmptyState() { var rowNum = $tableBody.find("tr").length; if (rowNum === 0) { $tableBody.html('<div class="empty-tip">暂无数据,点击"新增表格行"添加</div>'); } } // 拓展函数:收集表格数据(供表单提交使用) window.collectTableData = function() { var dataList = []; $tableBody.find("tr").each(function() { var $tds = $(this).find("td"); dataList.push({ index: $tds.eq(0).text(), content: $tds.eq(1).text() }); }); return dataList; }; }); </script> </body> </html>javascript
运行
var $tableBody = $("#tableBody"); var $addBtn = $("#addTableRow");$("#tableBody")会重复查询 DOM,缓存节点可减少 80% 以上的 DOM 查询开销;$,便于区分普通变量,提升代码可读性。javascript
运行
$tableBody.on("click", ".del-btn", function() { ... })$(".del-btn").click(),新增行的删除按钮因初始化时不存在,点击会完全失效;将 “重置序号”“检查空状态” 等逻辑封装为独立函数,符合 “单一职责原则”:
resetRowIndex():专注处理序号重排,后续修改序号规则只需改这一个函数;checkEmptyState():统一处理空状态展示,便于后续修改空状态文案 / 样式;confirm()拦截误操作,符合企业级产品交互规范;javascript
运行
window.jQuery || document.write('<script src="../js/jquery-3.7.1.min.js"><\/script>');将静态文本改为可编辑输入框,满足数据录入需求:
javascript
运行
// 改造新增行逻辑:内容列改为输入框 var newTr = $(` <tr> <td>${rowCount}</td> <td><input type="text" value="新增内容" class="edit-input"></td> <td><button class="del-btn">删除</button></td> </tr> `); // 同步修改数据收集函数 window.collectTableData = function() { var dataList = []; $tableBody.find("tr").each(function() { var $tds = $(this).find("td"); dataList.push({ index: $tds.eq(0).text(), // 读取输入框值 content: $tds.eq(1).find(".edit-input").val() }); }); return dataList; };html
预览
<!-- 新增全选列 --> <thead> <tr> <th><input type="checkbox" id="selectAll"></th> <th>序号</th> <th>内容</th> <th>操作</th> </tr> </thead> <!-- 新增批量删除按钮 --> <button class="add-btn" style="background: #f97316;" id="batchDelBtn">批量删除选中行</button>javascript
运行
// 全选/取消全选 $("#selectAll").on("click", function() { var isChecked = $(this).prop("checked"); $tableBody.find("tr").each(function() { $(this).find("td:first input").prop("checked", isChecked); }); }); // 批量删除 $("#batchDelBtn").on("click", function() { var $checkedRows = $tableBody.find("tr:has(input:checked)"); if ($checkedRows.length === 0) { alert("请选择要删除的行"); return; } if (confirm(`确定要删除选中的 ${$checkedRows.length} 行吗?`)) { $checkedRows.remove(); resetRowIndex(); checkEmptyState(); } });javascript
运行
// 提交前校验 window.validateTableData = function() { var isValid = true; $tableBody.find("tr").each(function(index) { var content = $(this).find("td:eq(1)").text().trim(); if (content === "" || content === "新增内容") { alert(`第 ${index + 1} 行内容不能为空,请填写后提交`); isValid = false; return false; // 终止遍历 } }); return isValid; };| 常见问题 | 根本原因 | 解决方案 |
|---|---|---|
| 删除按钮点击无反应 | 直接绑定事件到动态元素 | 改用事件委托,绑定到静态父元素(如 tbody) |
| 序号重排遗漏部分行 | 选择器范围错误 | 确保resetRowIndex()只遍历tbody下的tr,排除空状态提示 |
| 移动端表格变形 | 未做响应式适配 | 给表格容器加overflow-x: auto,设置表格最小宽度 |
| jQuery 未定义 | CDN 加载失败 | 增加降级逻辑,优先 CDN 后本地文件 |
| 数据收集为空 | 空状态提示被误判为行 | 收集数据时过滤.empty-tip元素 |
javascript
运行
$.fn.dynamicTable = function(options) { // 插件逻辑:新增、删除、序号重置等 }; // 使用:$("#myTable").dynamicTable({/* 配置项 */});String.concat(),并补充 ES6 垫片。