原生 不适合多条日志独立展开,因其无状态持久化、无键盘支持(需 tabindex 和 role="button")、 aria 支持弱、无视觉反馈;须配合 js 用 localstorage 记录状态、toggle 事件监听及语义化 html 结构(如 、 包裹、aria-labelledby)方可实现可访问、可记忆、可检索的更新日志。

<details></details> 标签本身不支持嵌套展开状态持久化,也不响应 click 事件冒泡外的交互(比如回车触发),直接用它做更新日志容易出现「点开一个,其他自动收起」「刷新后全部闭合」「键盘用户无法操作」等问题。得配合少量 JS 和语义化结构才能真正友好。
为什么原生 <details></details> 不适合多条日志独立展开
浏览器对多个 <details></details> 的默认行为是各自独立——这点其实 OK;但问题出在:没有视觉反馈告诉用户哪条已展开、无法记忆上次状态、<summary></summary> 不支持 role="button" 以外的 ARIA 属性,导致屏幕阅读器识别率低。
实操建议:
- 每条日志必须用独立的
<details></details>包裹,不能共用一个 - 给
<summary></summary>显式添加tabindex="0"和role="button",否则键盘Enter/Space无法触发 - 避免在
<summary></summary>里放<h3></h3>或<p></p>—— 会破坏可访问性层级,改用<span></span>+ CSS 控制样式 - 不要依赖
open属性硬编码展开状态,它无法跨页面保留
用 localStorage 记住用户展开偏好
用户点开 v2.3.1 的详情,下次进来还希望它是开的。原生 <details></details> 不提供钩子,得监听 toggle 事件手动存取。
示例逻辑:
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
document.querySelectorAll('details').forEach(details => {
const key = `changelog-${details.dataset.version}`;
if (localStorage.getItem(key) === 'true') details.open = true;
details.addEventListener('toggle', () => {
localStorage.setItem(key, details.open.toString());
});
});
注意点:
- 必须用
dataset.version这类自定义属性标识每条日志,不能靠索引(顺序可能变) -
toggle事件在 Safari 中兼容性良好,但旧版 iOS Safari 需要 polyfill,建议检查supports再绑定 - 如果日志量大(>50 条),批量读写
localStorage可能卡顿,考虑节流或改用sessionStorage
让时间线和版本号具备语义与可检索性
纯视觉排版(比如用 <hr> 分隔)对搜索引擎和辅助技术不友好。更新日志本质是「按时间倒序排列的带版本标识的变更列表」,应利用 HTML5 结构化标签强化含义。
推荐结构:
<section aria-labelledby="log-title"><h2 id="log-title">更新日志</h2>
<ol reversed>
<li>
<details data-version="2.3.1"><summary tabindex="0" role="button"><span>v2.3.1(2024-06-15)</span>
</summary><ul><li>修复导出 CSV 时中文乱码</li></ul></details>
</li>
</ol></section>
关键点:
-
<ol reversed></ol>告诉浏览器这是倒序列表,比纯<div> 更利于爬虫理解时序 <li>每个 <code><details></details>外包一层<li>,保持列表完整性 -
aria-labelledby关联标题,避免屏幕阅读器重复读「details」二字 - 版本号和日期放在
<summary></summary>内同一行,方便快捷键跳转时一并获取
最常被忽略的是键盘焦点管理:用户用 Tab 进入 <summary></summary> 后,按 Enter 应该展开/收起,但默认只在 Chrome/Firefox 生效,Safari 需要额外 preventDefault 并手动切换 open 属性。这个细节没处理好,等于把键盘用户挡在门外。










