npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

toc-nav

v0.0.6

Published

一个轻量级的目录导航组件,自动生成页面标题的可交互目录菜单

Readme

Toc Nav

一个轻量级的目录导航组件,自动生成页面标题的可交互目录菜单,支持滚动高亮和平滑跳转。
(在此之前,我尝试了 neotoctocbot,都不太满意,两者都是以文档为滚动区域,如果DIV局部滚动则不支持,而且实现代码量都非常巨大,也没有使用浏览更为先进的API!)

📺 在线演示

查看在线演示 | 查看源码

特性

  • 🚀 自动扫描 - 自动扫描页面中的 H1-H6 标题标签
  • 🎯 智能高亮 - 使用 IntersectionObserver API 实现滚动时自动高亮当前章节
  • 🔗 平滑跳转 - 点击目录项平滑滚动到对应标题位置
  • 🔄 动态刷新 - 支持动态内容更新后刷新目录
  • 📍 Hash 支持 - 支持 URL Hash 定位
  • 🎨 样式可定制 - 提供默认样式,支持自定义覆盖
  • 📦 零依赖 - 仅依赖 lodash-es,体积小巧
  • 💪 TypeScript - 使用 TypeScript 编写,提供完整的类型定义

安装

使用 npm 安装(推荐)

npm install toc-nav

或使用 CDN 引入,将项目内的 dist/index.global.js 拿出来用

<!-- 引入组件 -->
<script src="https://cdn.jsdelivr.net/npm/toc-nav"></script>

<!-- 引入样式 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/toc-nav/docs/dist/style.css">

<script>
  // 全局变量 TocNav 可用
  new TocNav.TocNav({
    contentElement: document.getElementById('content'),
    tocElement: document.getElementById('toc-container')
  });
</script>

🎨 本地运行示例

项目包含了一个完整的示例页面,展示了所有功能。运行步骤:

  1. 克隆项目并安装依赖
git clone https://github.com/dingshaohua-com/toc-nav.git
cd toc-nav
npm install
  1. 启动用例
npm run dev

示例页面将自动打开!

  1. 构建项目 其实启动用例的时候,就会触发自动构建!
npm run build

快速开始

npm 方式

import 'toc-nav/style.css';
import { TocNav } from 'toc-nav';

// 创建目录容器
const tocElement = document.getElementById('toc-container');

// 初始化 TOC
new TocNav({
  contentElement: document.getElementById('content'), // 内容容器
  tocElement: tocElement,                             // 目录容器
});

CDN 方式

<!DOCTYPE html>
<html>
<head>
  <title>TOC Menu Demo</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/toc-nav/docs/dist/style.css">
</head>
<body>
  <!-- 目录容器 -->
  <div id="toc-container"></div>

  <!-- 内容容器 -->
  <div id="content">
    <h1 id="section-1">第一章</h1>
    <p>内容...</p>

    <h2 id="section-1-1">1.1 小节</h2>
    <p>内容...</p>

    <h2 id="section-1-2">1.2 小节</h2>
    <p>内容...</p>

    <h1 id="section-2">第二章</h1>
    <p>内容...</p>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/toc-nav"></script>
  <script>
    new TocNav.TocNav({
      contentElement: document.getElementById('content'),
      tocElement: document.getElementById('toc-container')
    });
  </script>
</body>
</html>

HTML 结构要求

确保你的标题标签都有唯一的 id 属性:

<div id="content">
  <h1 id="section-1">第一章</h1>
  <p>内容...</p>

  <h2 id="section-1-1">1.1 小节</h2>
  <p>内容...</p>

  <h2 id="section-1-2">1.2 小节</h2>
  <p>内容...</p>
</div>

API

构造函数

new TocNav(config: Config)

Config 配置项

| 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | contentElement | HTMLElement | 是 | 需要扫描标题的内容容器元素 | | tocElement | HTMLElement | 是 | 用于渲染目录的容器元素 |

实例方法

refresh()

刷新目录状态,适用于以下场景:

  • 编辑器内容变更
  • 异步数据加载后
  • 动态添加/删除标题
const toc = new TocNav({
  contentElement: document.getElementById('content'),
  tocElement: document.getElementById('toc-container')
});

// 内容更新后刷新目录
setTimeout(() => {
  document.getElementById('content').innerHTML += '<h2 id="new-section">新章节</h2>';
  toc.refresh(); // 刷新目录
}, 1000);

样式定制

组件提供了默认样式,你可以通过覆盖 CSS 类来自定义样式:

默认 CSS 类

  • .toc-list - 目录列表容器
  • .toc-item - 目录项
  • .toc-item.active - 高亮的目录项
  • .level-3, .level-4 - 不同层级的缩进

自定义样式示例

/* 自定义高亮颜色 */
.toc-item.active {
  color: #ff6b6b;
  border-left-color: #ff6b6b;
  background: rgba(255, 107, 107, 0.1);
}

/* 自定义字体大小 */
.toc-item {
  font-size: 16px;
}

/* 自定义侧边线颜色 */
.toc-list {
  border-left-color: #ddd;
}

高级用法

在滚动容器中使用

const scrollContainer = document.getElementById('scroll-container');

new TocNav({
  contentElement: scrollContainer,
  tocElement: document.getElementById('toc-container'),
});

在 SPA 应用中使用

适用于 React、Vue、Angular 等单页应用:

React 示例

import { useEffect, useRef } from 'react';
import { TocNav } from 'toc-nav';
import 'toc-nav/style.css';

function App() {
  const contentRef = useRef(null);
  const tocRef = useRef(null);
  const tocInstanceRef = useRef(null);

  useEffect(() => {
    if (contentRef.current && tocRef.current) {
      tocInstanceRef.current = new TocNav({
        contentElement: contentRef.current,
        tocElement: tocRef.current
      });
    }
  }, []);

  // 当内容更新时刷新目录
  const handleContentUpdate = () => {
    tocInstanceRef.current?.refresh();
  };

  return (
    <div>
      <div ref={tocRef}></div>
      <div ref={contentRef}>
        <h1 id="title">标题</h1>
        <p>内容...</p>
      </div>
    </div>
  );
}

Vue 示例

<template>
  <div>
    <div ref="tocContainer"></div>
    <div ref="contentContainer">
      <h1 id="title">标题</h1>
      <p>内容...</p>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import { TocNav } from 'toc-nav';
import 'toc-nav/style.css';

const tocContainer = ref(null);
const contentContainer = ref(null);
let tocInstance = null;

onMounted(() => {
  tocInstance = new TocNav({
    contentElement: contentContainer.value,
    tocElement: tocContainer.value
  });
});

// 当内容更新时
const handleContentUpdate = () => {
  tocInstance?.refresh();
};
</script>

浏览器兼容性

  • Chrome ≥ 51
  • Firefox ≥ 55
  • Safari ≥ 12.1
  • Edge ≥ 79

需要支持以下 Web API:

  • IntersectionObserver
  • ResizeObserver
  • scrollend 事件

类型定义

interface TocItem {
  id: string;      // 标题的 ID
  text: string;    // 标题文本
  level: number;   // 标题层级 (1-6)
}

interface Config {
  contentElement: HTMLElement;  // 内容容器
  tocElement: HTMLElement;      // 目录容器
}

注意事项

  1. 标题必须有 ID:确保你的标题标签都有唯一的 id 属性,组件才能正确生成锚点链接
  2. 容器滚动:如果内容在特定容器内滚动(而非整个页面),请将该容器传入 contentElement
  3. 动态内容:如果内容是动态加载的,记得在内容加载完成后调用 refresh() 方法
  4. CDN 使用:通过 CDN 引入时,组件导出在 TocNav 命名空间下,需要使用 TocNav.TocNav 访问类

打包说明

本项目使用 tsup 打包,输出以下格式:

  • ESM (dist/index.mjs) - 用于现代构建工具(Vite、Webpack 5+)
  • CJS (dist/index.js) - 用于 Node.js 和旧版构建工具
  • IIFE (dist/index.global.js) - 用于浏览器直接引入(CDN)

开发

# 安装依赖
npm install

# 构建
npm run build

🚀 部署示例页面到 GitHub Pages

项目包含了一个完整的示例页面(位于 docs/ 目录),你可以轻松部署到 GitHub Pages:

  1. 推送代码到 GitHub
git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/dingshaohua-com/toc-nav.git
git push -u origin main
  1. 启用 GitHub Pages

    • 进入 GitHub 仓库页面
    • 点击 SettingsPages
    • Source 下拉菜单中选择 main 分支
    • 在文件夹下拉菜单中选择 /docs
    • 点击 Save
  2. 访问你的示例页面

    • 几分钟后,访问 https://dingshaohua-com.github.io/toc-nav/
    • 即可看到完整的在线演示

注意: 确保在部署前先运行 npm run build 构建项目,否则示例页面无法正常加载组件。

License

MIT

贡献

欢迎提交 Issue 和 Pull Request!

更新日志

0.0.5

  • 初始版本
  • 支持自动扫描标题
  • 支持滚动高亮
  • 支持平滑跳转
  • 支持动态刷新
  • 支持 ESM、CJS、IIFE 多种格式