You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用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

火山引擎 最新活动