监听 details 元素的 toggle 事件是唯一可靠触发时机,它在 open 属性变更后稳定执行,兼容现代浏览器;需用 data-src 延迟图片加载,动态赋值 src;多个 details 实现手风琴需手动同步 open 状态并防死循环;details 折叠不减少首屏资源加载,真优化需动态注入内容。

监听 toggle 事件是唯一可靠触发时机
很多人试图监听 summary 的 click,但这是错的——键盘用户按空格或回车也能展开,而 click 不会触发。只有 details 元素自身的 toggle 事件,才能在 open 属性真正变更后稳定执行。
这个事件兼容性已足够好(Chrome 12+、Firefox 49+、Safari 15.4+),IE 完全不支持,但 IE 已退出主流;若仍需兜底,先用 'open' in document.createElement('details') 检测特性,再降级。
- 不要给
summary绑click,它无法覆盖键盘交互 -
toggle是 DOM Level 3 标准事件,不会冒泡到父级,需直接监听目标details - 事件对象
e.target.open就是当前最新状态,无需查 DOM 属性
data-src + toggle 才能真正延迟图片加载
浏览器不管 details 是否折叠,只要 <img src="..." alt="HTML toggle事件实现懒加载折叠内容的方法" > 在初始 HTML 里,就会立即发起请求。display: none 或折叠状态对资源加载零影响。
真正可控的方式是:把 src 拿掉,换成 data-src,等 toggle 触发且 e.target.open === true 时,再赋值回去。
立即学习“前端免费学习笔记(深入)”;
- 初始 HTML 中写:
<img alt="...">,不设src - JS 中检查
img.src是否为空,避免重复赋值(比如用户快速点开又收起) - 若
details默认open,页面加载完就得手动初始化一次img.src = img.dataset.src - 别依赖
loading="lazy"—— 它只对视口滚动生效,和折叠状态无关
多个 details 实现手风琴互斥要遍历兄弟节点
原生 details 之间完全独立,点击一个不会关掉其他。要实现“展开一个、收起其余”,必须在 toggle 回调里手动处理。
关键不是加 class 或改样式,而是同步更新其他兄弟节点的 open 属性——这会触发它们各自的 toggle 事件,形成连锁响应,所以得加守卫逻辑防止死循环。
- 用
document.querySelectorAll('details')获取全部,再排除自身 - 只对
e.target.open === true的情况才去关闭其他,避免收起时误操作 - 关闭其他时直接设
otherDetails.open = false,不要用removeAttribute('open'),后者不保证 DOM 属性同步 - 如果用了自定义 class(如
is-open)做样式兜底,记得同步 toggle class
默认展开时内容仍参与首屏渲染,别指望靠折叠提速
details 折叠只是视觉控制,内部所有 HTML、<script></script>、<img alt="HTML toggle事件实现懒加载折叠内容的方法" > 都会在页面解析阶段被处理。DOM 大小、JS 执行、资源请求该发生的全发生,FCP/LCP 一点没改善。
真想优化首屏,得把非关键内容从初始 HTML 剥离:用 fetch() 动态加载片段,再注入到 details 内部。但注意注入后 <script></script> 不会自动执行,得手动 eval 或 createScript。
- 服务端返回的必须是纯净 HTML 片段(无
/) - 注入用
innerHTML最简单,但含脚本需额外处理 - 若内容含 iframe 或第三方 widget,动态注入可能破坏其生命周期,优先考虑服务端渲染或 SSR
- 别为了“看起来懒”而把大段文本塞进
details——它不减少解析时间



















