如何用JQuery实现tbody节点拆分与新节点插入?现有代码故障求解决
问题描述
我有如下HTML结构:
<table> <tbody> <tr><td><button> Split </button></td></tr> <tr><td><button> Split </button></td></tr> <tr><td><button> Split </button></td></tr> <tr><td><button> Split </button></td></tr> <tr><td><button> Split </button></td></tr> <tr><td><button> Split </button></td></tr> </tbody> </table>
点击任意按钮时需要实现以下功能:
- 将tbody节点拆分为两个tbody节点,比如点击第二个按钮时,前两行归第一个tbody,剩余行归第二个tbody;
- 在这两个tbody节点之间插入一个新的tbody节点;
- 新tbody的innerHTML为:
<tr><td><p> Clicked </p></td></tr>
点击第二个按钮后的期望HTML结构:
<table> <tbody> <tr><td><button> Split </button></td></tr> <tr><td><button> Split </button></td></tr> </tbody> <tbody> <tr><td><p> Clicked </p></td></tr> </tbody> <tbody> <tr><td><button> Split </button></td></tr> <tr><td><button> Split </button></td></tr> <tr><td><button> Split </button></td></tr> <tr><td><button> Split </button></td></tr> </tbody> </table>
我的JavaScript代码无法实现该功能,代码如下:
$("button").on("click", function() { var currentRow = $(this).parent().parent(); var htmlStr = "</tbody>"; htmlStr += "<tbody>"; htmlStr += "<tr><td><p>Clicked</p></td></tr>"; htmlStr += "</tbody>"; htmlStr += "<tbody>"; currentRow.after(htmlStr); console.log($("table").html()); });
另外,代码最后一行输出的HTML格式不整洁,希望了解优化方法。
解决方案
1. 核心功能实现修正
直接拼接</tbody>和<tbody>字符串插入DOM的方式不可行,浏览器会自动修正不合法的HTML结构,不会按预期拆分原tbody。正确做法是直接操作DOM元素:
$("button").on("click", function() { // 获取当前按钮所在行 const $currentRow = $(this).closest("tr"); // 获取原tbody容器 const $originalTbody = $currentRow.closest("tbody"); // 获取当前行在原tbody中的索引 const rowIndex = $originalTbody.find("tr").index($currentRow); // 创建新tbody,存放当前行之后的所有行 const $newTbody = $("<tbody></tbody>"); $currentRow.nextAll().appendTo($newTbody); // 创建中间的提示tbody const $clickedTbody = $("<tbody></tbody>").html('<tr><td><p> Clicked </p></td></tr>'); // 按顺序插入新元素 $originalTbody.after($clickedTbody).after($newTbody); // 格式化输出HTML console.log(formatHTML($("table").html())); });
2. HTML输出格式化方法
可以用轻量的原生函数实现HTML格式化,避免输出杂乱的结构:
function formatHTML(html) { // 清除冗余空格与换行 let formatted = html.replace(/^\s+|\s+$/g, '') .replace(/>\s+</g, '><') .replace(/</g, '\n<'); // 处理缩进层级 let indentLevel = 0; const lines = formatted.split('\n'); formatted = lines.map(line => { // 闭合标签减少缩进 if (line.match(/^<\/.*>/)) { indentLevel--; } const indent = ' '.repeat(indentLevel); // 非自闭合标签增加缩进 if (line.match(/^<[^\/].*>/) && !line.match(/\/>$/)) { indentLevel++; } return indent + line; }).join('\n'); return formatted; }
代码说明
- 用
closest()替代多层parent(),更可靠地定位父元素; - 通过DOM元素移动(
appendTo())拆分tbody,确保浏览器能正确识别结构; - 格式化函数通过正则处理标签和缩进,让输出的HTML结构清晰易读。
内容的提问来源于stack exchange,提问作者The_Inquisitioner
相关产品推荐
相关产品推荐

