要实现可折叠代码块,须组合并转义HTML字符;须为首个子元素,须紧随其后;动态展开时需监听toggle事件重触发语法高亮。

标签本身不支持语法高亮或代码块渲染,它只是语义化折叠容器;要实现“可折叠的代码块”,必须手动组合 、 和 <code></code>,并确保 <code><code></code> 的内容被正确转义或由编辑器预处理。</code>
为什么直接写 <details><summary>Code</summary><pre class="brush:php;toolbar:false;"><code>console.log(1)</code>
常见错误是未对 HTML 特殊字符做转义,导致浏览器把 内的尖括号解析为标签而非文本。例如:for (let i = 0; i 中的 会被截断解析,后续内容消失或报错。
- 编辑器若为富文本(如 TinyMCE、CKEditor),默认会过滤或破坏
<code></code> 结构,需开启 <code>allowedContent</code> 或禁用 HTML 清洗
- 若为 Markdown 编辑器(如 Toast UI Editor、Obsidian),需确认是否支持原生 HTML 嵌入 —— 多数默认关闭,需设
html: true或等效配置 - 服务端渲染时(如 Jekyll、Hugo),模板引擎可能自动转义,需用
{{ raw }}...{{ endraw }}或{{ .RawHTML | safeHTML }}绕过
正确嵌套结构与转义方式
核心是保证 <code></code> 内容作为纯文本存在。最稳妥的做法是:在 HTML 源码中手动将 <code> 替换为 <code>,<code>></code> 替换为 <code>></code>,<code>&</code> 替换为 <code>&</code>。</code></code>
<details><summary>点击展开 JS 示例</summary><pre class="brush:php;toolbar:false;"><code class="js">function hello() {
console.log("world");
return true && false;
}</code>
-
必须是的第一个子元素,否则折叠逻辑失效 -
应紧贴后,中间不能有空格或换行文本节点(某些旧版 Safari 会因此不渲染) - 如果依赖 Prism.js 或 Highlight.js,
class="js"是必需的触发标识,且需在展开后再调用Prism.highlightAll()
动态展开后语法高亮不生效?
因为 默认折叠时,部分高亮库(尤其是早期 Prism 版本)会跳过隐藏 DOM 的处理。解决方案不是改 CSS 显示,而是监听 toggle 事件重触发:
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('details').forEach(details => {
details.addEventListener('toggle', () => {
if (details.open && details.querySelector('code')) {
Prism.highlightElement(details.querySelector('code'));
}
});
});
});
- 不要用
details.addEventListener('click', ...)—— 点击不一定触发该事件,toggle才是标准行为 - 检查
Prism.highlightElement()是否已加载;若用模块化引入,需确保prism-core和对应语言插件都已 import - 若用 Highlight.js,替换为
hljs.highlightElement(codeEl),逻辑一致
真正容易被忽略的是:编辑器保存时是否保留原始 HTML 结构。很多所见即所得编辑器会在切换源码/可视化模式时自动“修复”嵌套,把 <code></code> 提到外面,或删掉 <code><details></details></code>。上线前务必查看浏览器实际渲染的 DOM,而不是编辑器里写的源码。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











