js实现目录
实现目录的基本思路
在JavaScript中实现目录功能通常涉及以下几个核心步骤:解析文档中的标题元素(如h1-h6),动态生成目录结构,并添加交互逻辑(如点击跳转)。以下是具体实现方法:
解析标题元素
使用document.querySelectorAll获取所有标题标签,并过滤出需要生成目录的层级(例如仅h2和h3):

const headings = document.querySelectorAll('h2, h3');
生成目录结构
遍历标题元素,创建嵌套的列表项(<ul>和<li>),并为每个标题添加锚点或id以便跳转:
const tocContainer = document.getElementById('toc');
const ul = document.createElement('ul');
headings.forEach(heading => {
const li = document.createElement('li');
const a = document.createElement('a');
a.textContent = heading.textContent;
a.href = `#${heading.id}`;
li.appendChild(a);
ul.appendChild(li);
});
tocContainer.appendChild(ul);
动态添加标题ID
若标题元素没有id,需动态生成唯一标识符:

headings.forEach((heading, index) => {
if (!heading.id) {
heading.id = `heading-${index}`;
}
});
高亮当前浏览章节
监听滚动事件,通过IntersectionObserver或计算元素位置实现目录高亮:
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
document.querySelectorAll('#toc a').forEach(a => {
a.classList.remove('active');
if (a.getAttribute('href') === `#${entry.target.id}`) {
a.classList.add('active');
}
});
}
});
}, { threshold: 0.5 });
headings.forEach(heading => observer.observe(heading));
完整代码示例
<div id="toc"></div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const headings = document.querySelectorAll('h2, h3');
const tocContainer = document.getElementById('toc');
const ul = document.createElement('ul');
// 动态生成目录
headings.forEach((heading, index) => {
if (!heading.id) heading.id = `heading-${index}`;
const li = document.createElement('li');
const a = document.createElement('a');
a.textContent = heading.textContent;
a.href = `#${heading.id}`;
li.appendChild(a);
ul.appendChild(li);
});
tocContainer.appendChild(ul);
// 高亮逻辑
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
document.querySelectorAll('#toc a').forEach(a => {
a.classList.remove('active');
if (a.getAttribute('href') === `#${entry.target.id}`) {
a.classList.add('active');
}
});
}
});
}, { threshold: 0.5 });
headings.forEach(heading => observer.observe(heading));
});
</script>
样式优化建议
为目录添加基础CSS样式,提升用户体验:
#toc {
position: fixed;
left: 20px;
top: 20px;
background: #f5f5f5;
padding: 10px;
border-radius: 4px;
}
#toc a.active {
font-weight: bold;
color: #0078d7;
}
注意事项
- 标题层级处理:若需支持多级嵌套(如
h3作为h2的子项),需在生成目录时增加层级判断逻辑。 - 性能优化:对大量标题使用
IntersectionObserver比监听scroll事件更高效。 - SEO友好:确保生成的锚点链接可被搜索引擎抓取。






