html无法自动生成目录,必须用javascript实现;推荐用document.queryselectorall选择器精准定位标题,配合insertadjacenthtml安全插入,再通过slugify规范生成id,最后处理多级嵌套与滚动高亮等进阶问题。

HTML 本身不提供自动目录(TOC)功能,所谓“自动生成”必须靠 JavaScript 实现;纯 HTML+CSS 做不了,别在 <h1></h1> 上瞎加属性指望浏览器自动出目录。
用 document.querySelectorAll 找标题最稳
浏览器兼容性好、语义清晰,比正则匹配 HTML 字符串或遍历 childNodes 更可靠。关键是要选对选择器:
-
document.querySelectorAll('h1, h2, h3, h4, h5, h6')能抓全所有标题,但可能混入页眉/侧边栏的非正文标题 - 更稳妥的是加容器限定,比如
document.querySelectorAll('.article-content h2, .article-content h3') - 注意:
querySelectorAll返回的是静态 NodeList,不能用forEach直接调(老版本 IE 不支持),得转成数组或用for...of
insertAdjacentHTML 比 innerHTML += 安全
很多人习惯拼字符串再赋给 innerHTML,但这样会销毁已绑定的事件、重置表单值、触发重复解析。正确做法是用 insertAdjacentHTML 插入到指定位置:
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
const tocEl = document.getElementById('toc');
tocEl.insertAdjacentHTML('beforeend', '
-
'beforeend'表示插到元素内部末尾,类似append()但兼容 IE - 避免用
'afterbegin'或'beforebegin'往外插,容易破坏 DOM 结构预期 - 生成的
href值必须和目标id严格一致(区分大小写、不能有空格)
给标题自动加 id 要防重复和特殊字符
不是所有标题都有 id,手动加不现实,得脚本补。但直接用 textContent 当 id 会出问题:
- 中文、空格、标点会导致
id非法(如id="第二章:入门"是无效的) - 相同标题(比如多个「小结」)会导致
id冲突,锚点跳转错乱 - 推荐做法:用
slugify思路——转小写、去标点、空格换短横、去重后缀计数 - 简单实现可参考:
titleEl.id = titleText.replace(/[^\w\u4e00-\u9fa5]+/g, '-').replace(/^-+|-+$/g, '') || 'section-' + i
真正难的不是生成目录,而是处理多级嵌套时的缩进逻辑、滚动时的高亮同步、以及 SSR(服务端渲染)环境下 JS 还没执行前的空白期体验——这些一碰就绕不开 DOM 生命周期和首屏渲染时机,新手容易卡在这儿反复刷新看不出来效果。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










