details的open属性无法通过click事件阻止,因展开/收起由浏览器内部机制触发;应使用toggle事件回调中逻辑修正,或通过移除summary、禁用交互区域等方式彻底禁用。

details的open属性不能被click事件阻止
直接监听click并调用event.preventDefault()对<summary></summary>或<details></details>无效——浏览器原生的展开/收起行为不依赖click事件,而是由内部机制触发,preventDefault对其无影响。
真正能干预展开行为的是toggle事件回调里的逻辑
toggle事件在用户交互(鼠标点击、空格键、回车键)完成状态切换后才派发,此时el.open已是新值。它不可取消,但你可以在回调里“反向修正”:
- 想禁止展开:监听
toggle后立即执行el.open = false - 想禁止收起:同理设为
true,但注意这会破坏键盘可访问性(如按空格无法关闭) - 更稳妥的做法是加条件判断:
if (shouldAllowToggle) return;,再手动重置
阻止默认行为的替代方案:禁用summary交互区域
如果目标是彻底禁用折叠功能(比如内容已加载完毕、状态锁定),不要靠JS拦截事件,而应从结构和样式入手:
- 移除
<summary></summary>的可聚焦能力:summary { pointer-events: none; } - 同时加
tabindex="-1"防止键盘聚焦:<summary tabindex="-1"></summary> - 避免使用
disabled属性——<summary></summary>不支持该属性,写了也无效 - 若需视觉提示禁用状态,用
details[open] summary:disabled无效,应改用自定义class + CSS
容易被忽略的兼容性陷阱
在iOS Safari或微信X5内核中,强行用JS反复设置el.open可能引发状态抖动或点击穿透;嵌套<details></details>时,外层toggle事件甚至可能不触发。最稳的方式不是“阻止”,而是提前控制DOM结构:该禁用时,干脆不渲染<summary></summary>,或用<div>替代整个<code><details></details>结构。











