如何用HTML制作类似维基百科的目录
嘿,刚好之前折腾过类似的需求,给你几个超省心的实现方案,不用手动一个个敲超链接那么麻烦:
方案1:原生HTML+锚点(零JS,最轻量化)
这个方案完全用浏览器原生特性实现,不用写任何JS,代码简单还稳定:
首先,给页面里的所有标题加上唯一的id(作为锚点目标),然后用<details>和<summary>做可折叠的目录容器,里面放指向这些锚点的链接就行。
<!-- 目录区块 --> <details class="wiki-toc" open> <summary>目录</summary> <ul> <li><a href="#section1">1. 第一部分标题</a></li> <li><a href="#section2">2. 第二部分标题</a> <ul> <li><a href="#section2-1">2.1 子部分标题</a></li> </ul> </li> <li><a href="#section3">3. 第三部分标题</a></li> </ul> </details> <!-- 页面内容 --> <h2 id="section1">1. 第一部分标题</h2> <p>这里是第一部分的内容...</p> <h2 id="section2">2. 第二部分标题</h2> <p>这里是第二部分的内容...</p> <h3 id="section2-1">2.1 子部分标题</h3> <p>这里是子部分的内容...</p> <h2 id="section3">3. 第三部分标题</h2> <p>这里是第三部分的内容...</p>
再加几行CSS,就能复刻维基百科的目录样式:
.wiki-toc { border: 1px solid #a2a9b1; background-color: #f8f9fa; padding: 10px; margin: 1em 0; border-radius: 2px; } .wiki-toc summary { font-weight: bold; cursor: pointer; margin-bottom: 8px; } .wiki-toc ul { list-style-type: none; padding-left: 20px; margin: 0; } .wiki-toc li { margin: 4px 0; } .wiki-toc a { text-decoration: none; color: #0645ad; } .wiki-toc a:hover { text-decoration: underline; }
优点:完全依赖原生HTML/CSS,兼容性拉满,不用考虑JS报错的问题,折叠/展开都是浏览器自带的交互逻辑。
方案2:自动生成目录(适合内容多的页面)
如果页面标题特别多,手动写目录链接太费时间,还容易出错,可以用几行JS自动生成目录,一劳永逸:
<!-- 先放一个空的目录容器 --> <details class="wiki-toc" open> <summary>目录</summary> <div id="toc-container"></div> </details> <!-- 页面内容(标题不用手动加id,脚本会自动生成) --> <h2>1. 第一部分标题</h2> <p>这里是第一部分的内容...</p> <h2>2. 第二部分标题</h2> <p>这里是第二部分的内容...</p> <h3>2.1 子部分标题</h3> <p>这里是子部分的内容...</p> <h2>3. 第三部分标题</h2> <p>这里是第三部分的内容...</p> <script> // 自动生成目录的脚本 const headings = document.querySelectorAll('h2, h3'); const tocContainer = document.getElementById('toc-container'); const tocList = document.createElement('ul'); headings.forEach(heading => { // 给没有id的标题自动生成唯一id if (!heading.id) { heading.id = heading.textContent.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, ''); } const listItem = document.createElement('li'); const link = document.createElement('a'); link.href = `#${heading.id}`; link.textContent = heading.textContent; // 区分h2和h3,自动生成嵌套列表 if (heading.tagName === 'H3') { // 找到最近的父级h2 let prevH2 = heading.previousElementSibling; while (prevH2 && prevH2.tagName !== 'H2') { prevH2 = prevH2.previousElementSibling; } // 找到对应h2的目录项 let parentLi = Array.from(tocList.children).find(li => li.querySelector('a').href.includes(`#${prevH2.id}`) ); if (!parentLi) { parentLi = document.createElement('li'); tocList.appendChild(parentLi); } // 创建子列表(如果没有的话) let subList = parentLi.querySelector('ul'); if (!subList) { subList = document.createElement('ul'); parentLi.appendChild(subList); } subList.appendChild(listItem); } else { tocList.appendChild(listItem); } }); tocContainer.appendChild(tocList); </script>
这个脚本会自动扫描页面里的<h2>和<h3>标签,给它们生成唯一的id,然后自动构建嵌套的目录列表。后期修改标题或者新增章节,目录都会自动同步,完全不用手动维护。
如果是用静态站点生成器(比如Jekyll、Hexo),这类工具一般都自带目录生成插件,直接配置就行,但纯HTML页面用上面的方案就足够了。
内容的提问来源于stack exchange,提问作者Farmer Joe




