直接嵌套会失效,因浏览器自动修正为同级结构导致父子关系丢失;必须用data-parent-id标记父子关系,通过queryselectorall精准匹配并切换hidden状态,动态计算colspan,逐级展开并分层维护状态。

为什么直接在里嵌套
会失效
浏览器会自动修正非法 HTML 结构,<tr></tr>
<tr></tr>
这种写法会被 DOM 解析器“拍平”——内层 <tr> 被提到外层同级,父子关系彻底丢失。结果就是 JS 找不到子行、点击无响应、折叠后错位。
<p>必须把子行作为独立 <code><tr> 插入主行正下方,且二者同属一个 <code><tbody>。不能靠视觉位置猜父子关系,得靠属性标记。
<ul>
<li>给主行加 <code>data-id="row-101",子行加 data-parent-id="row-101"
浏览器会自动修正非法 HTML 结构,<tr></tr>
<tr></tr>
hidden 属性(或统一 class 如 is-detail-row)visibility: hidden —— 它占布局空间,折叠后留白、滚动条异常如何用 JS 精准展开/收起对应子行
别依赖 nextElementSibling 向下找一行——表格里可能穿插合计行、分隔行、筛选后的行,DOM 顺序不可靠。唯一靠谱的是按 data-parent-id 匹配。
点击主行时,执行:
-
document.querySelectorAll('tr[data-parent-id="row-101"]')查出全部直属子行(注意:每次都要重新查,不缓存 NodeList) - 对每个匹配到的
<tr> 切换 <code>hidden属性,或增删is-hiddenclass - 同步更新主行的
aria-expanded值:el.setAttribute('aria-expanded', 'true') - 如果子行含表单或焦点元素,展开后应
focus()到第一个可聚焦项,满足无障碍要求 - 取主行第一个
<td> 或 <code><th> 的 <code>cellIndex+ 1,不如直接读table.rows[0].cells.length - 子行
<td> 的 <code>colspan设为该值,不要用 CSSwidth: 100%模拟 —— 表格布局不认这个 - 确保
border-collapse: collapse已设,否则折叠后边框间距异常、视觉断裂 - 主行标
data-level="1",其子行列标data-level="2" data-parent-id="row-101" - level-2 行再作为父级,其子行列标
data-level="3" data-parent-id="row-205"(id 来自某 level-2 行) - JS 展开时加条件:
tr[data-level="2"][data-parent-id="row-101"],不带 level 限制就会越级展开 - 箭头图标状态也要分层维护,比如用
data-expanded-level2="true"单独存状态,别混用一个aria-expanded
折叠后 colspan 和边框怎么不出错
子行 <td colspan="N"> 的 <code>N 必须等于当前表格实际列数。写死 colspan="3" 在动态列数场景下必然塌陷。
正确做法是运行时计算:
三级折叠怎么避免点一次全展开
三级不是“点根节点就展开全部”,而是逐级响应:点 level-1 行只展开 level-2 子行;再点某 level-2 行,才展开它下面的 level-3 行。
关键在过滤范围:
层级一多,data-parent-id 就成了唯一可信线索;class 名或 DOM 位置全是幻觉。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











