直接用display:none切换显隐最常见但易崩,因nextSibling定位不准、data-level缺失致父子关系丢失、visibility:hidden占位、状态与图标不同步、aria-expanded缺失影响可访问性。

直接用 浏览器解析 HTML 时会自动剥离文本节点(比如换行、空格),导致 图标方向和行显隐不同步,是用户最困惑的点——点了 ▶ 却没展开,或已收起但图标还是 ▼。根源在于状态没绑定到同一控制源。 屏幕阅读器靠 真正难的不是让行消失,而是让消失这件事对 DOM 结构、键盘操作、屏幕阅读器、后续 JS 查询都“透明且可控”。多一级嵌套,就要多一层 display: none 切换 显隐是最常见做法,但错在 DOM 定位不准、层级混乱、可访问性缺失——不是“能不能”,而是“怎么切才不崩”。 为什么 nextSibling 找不到目标行?
nextSibling 返回的是文本节点而非 。一旦中间有回车或注释, el.nextSibling 就失效。
nextElementSibling,它只认元素节点,跳过所有空白和注释 → 紧跟一个 ,中间不能插任何非元素内容
包裹数据行,得先确认目标行是否在同一
下,跨组时
nextElementSibling 会返回 null
data-level 怎么避免父子关系丢失?
不允许嵌套,强行写
... 会被浏览器自动“拍平”到同级,DOM 树里根本不存在父子路径。靠位置推断层级纯属碰运气。
data-level="1"、data-level="2",并配 data-parent-id="row-101" 指向父行 IDdocument.querySelectorAll('tr[data-level="2"][data-parent-id="row-101"]'),而不是 tr[data-level="2"]
visibility: hidden:它占布局空间,折叠后仍影响滚动条高度和点击热区箭头图标旋转和状态怎么保持同步?
icon.classList 和 row.style.display,改用统一状态标记:row.setAttribute('data-expanded', 'true')
tr[data-expanded="true"] .arrow { transform: rotate(90deg); }
data-expanded="false",避免 HTML 里硬写 style="display:none" 干扰动态增删aria-expanded 为什么不能省?
aria-expanded 判断当前是否可展开,没有它,视障用户完全不知道那行还能点、点了会发生什么。这不是“锦上添花”,是合规底线。
icon.setAttribute('aria-expanded', 'true') 和 targetRow.setAttribute('aria-hidden', 'false')
role="button",否则键盘按 Enter 或 Space 不响应 上——容易误触,应限定在带 role="button" 的 或 内
data-parent-id 过滤;少一个 aria-expanded,就等于关掉了一半用户的入口。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











