概述

因為文章太長,閱讀困難,所以看到別人部落格有的TOC功能,就找AI復刻

需求

  • 使用TOC快速定位
  • TOC隨著本文滾動定位當前位置
  • 手機寬度下不顯示TOC,改用回到頁首的懸浮按鈕取代

1. Hugo 配置設定

1.1 啟用 TOC 功能

hugo.toml 中啟用 TOC 功能:

點擊查看配置程式碼```toml [markup] [markup.tableOfContents] startLevel = 2 endLevel = 4 ordered = false ```

參數說明

  • startLevel = 2:從 H2 標題開始生成 TOC
  • endLevel = 4:到 H4 標題結束
  • ordered = false:使用無序列表格式

2. 自定義文章佈局

2.1 建立自定義 single.html

layouts/_default/single.html 中實現新的佈局結構:

點擊查看完整 HTML 佈局程式碼```html {{ define "main" }}
{{ if not .Params.menu }}

{{ .Title }}

{{ end }} {{ .Content }}

{{ range (.GetTerms "tags") }} #{{ lower .LinkTitle }} {{ end }}

{{ if not .Params.hideReply }} {{ with .Site.Params.author.email }}

{{ i18n "email-reply" }} ↪

{{ end }} {{ end }}
{{ end }} ```

3. CSS 樣式設計

3.1 側邊欄樣式

layouts/partials/custom_head.html 中添加 CSS:

點擊查看側邊欄 CSS 樣式```css /* 側邊章節導航樣式 - 獨立側邊欄 */ .toc-sidebar { position: fixed; top: 50%; right: 20px; transform: translateY(-50%); width: 280px; max-height: 80vh; overflow-y: auto; padding: 1.5rem; background: rgba(0, 0, 0, 0.8); backdrop-filter: blur(10px); border-radius: 12px; border: 1px solid rgba(255, 255, 255, 0.15); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); z-index: 1000; transition: all 0.3s ease; } .toc-sidebar:hover { background: rgba(0, 0, 0, 0.9); border-color: rgba(255, 255, 255, 0.25); } /* 文章內容保持原有佈局 */ .article-content { max-width: 800px; margin: 0 auto; padding: 0 1rem; } .toc-sidebar h3 { margin: 0 0 1rem 0; font-size: 1rem; font-weight: 600; color: var(--primary-color, #fff); border-bottom: 1px solid rgba(255, 255, 255, 0.2); padding-bottom: 0.5rem; } .toc-sidebar ul { list-style: none; padding: 0; margin: 0; } .toc-sidebar li { margin: 0.25rem 0; } .toc-sidebar a { display: block; padding: 0.25rem 0.5rem; color: rgba(255, 255, 255, 0.7); text-decoration: none; border-radius: 4px; transition: all 0.2s ease; font-size: 0.9rem; line-height: 1.4; } .toc-sidebar a:hover { background: rgba(255, 255, 255, 0.1); color: var(--primary-color, #fff); } .toc-sidebar a.active { background: rgba(255, 255, 255, 0.15); color: var(--primary-color, #fff); font-weight: 500; } /* 不同層級的縮排 */ .toc-sidebar ul ul { margin-left: 1rem; border-left: 1px solid rgba(255, 255, 255, 0.1); padding-left: 0.5rem; } .toc-sidebar ul ul ul { margin-left: 1rem; } ```

3.2 回到頂部按鈕樣式

點擊查看回到頂部按鈕 CSS 樣式```css /* 回到頂部按鈕樣式 */ .back-to-top-btn { position: fixed; bottom: 2rem; right: 2rem; width: 50px; height: 50px; background: rgba(0, 0, 0, 0.8); backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 50%; color: white; cursor: pointer; display: none; align-items: center; justify-content: center; z-index: 1000; transition: all 0.3s ease; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); } .back-to-top-btn:hover { background: rgba(0, 0, 0, 0.9); border-color: rgba(255, 255, 255, 0.4); transform: translateY(-2px); box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4); } .back-to-top-btn:active { transform: translateY(0); } .back-to-top-btn.visible { display: flex; animation: fadeInUp 0.3s ease; } @keyframes fadeInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } ```

3.3 響應式設計

點擊查看響應式設計 CSS 樣式```css /* 響應式設計 */ @media (max-width: 1024px) { .toc-sidebar { width: 240px; right: 15px; } } @media (max-width: 768px) { /* 手機版隱藏 TOC */ .toc-sidebar { display: none; } /* 確保文章內容在手機版有足夠的邊距 */ .article-content { max-width: 100%; padding: 0 1.5rem; } .back-to-top-btn { bottom: 1.5rem; right: 1.5rem; width: 45px; height: 45px; } } /* 平板版調整 */ @media (max-width: 1024px) and (min-width: 769px) { .toc-sidebar { width: 220px; padding: 1rem; font-size: 0.9rem; } .toc-sidebar h3 { font-size: 0.9rem; } .toc-sidebar a { font-size: 0.85rem; padding: 0.2rem 0.4rem; } } ```

4. 標題間距優化

4.1 改善文章可讀性

點擊查看標題間距 CSS 樣式```css /* 調整標題間距 */ .article-content h2 { margin-top: 4.5rem; margin-bottom: 1.5rem; padding-top: 0.5rem; padding-bottom: 0.5rem; } .article-content h3 { margin-top: 2.5rem; margin-bottom: 1.2rem; padding-top: 0.4rem; padding-bottom: 0.4rem; } .article-content h4 { margin-top: 2rem; margin-bottom: 1rem; padding-top: 0.3rem; padding-bottom: 0.3rem; } /* 第一個標題不需要上邊距 */ .article-content h2:first-child, .article-content h3:first-child, .article-content h4:first-child { margin-top: 0; } /* 段落與標題之間的間距 */ .article-content p { margin-bottom: 1.2rem; line-height: 1.6; } /* 列表與標題之間的間距 */ .article-content ul, .article-content ol { margin-top: 1rem; margin-bottom: 1.5rem; } .article-content li { margin-bottom: 0.5rem; line-height: 1.5; } /* 確保標題有正確的錨點 ID */ .article-content h2, .article-content h3, .article-content h4 { scroll-margin-top: 2rem; } ```

5. 需求描述

5.1 桌面版功能

  • 固定側邊欄:右側固定位置的章節目錄
  • 自動高亮:滾動時自動高亮當前章節
  • 智能滾動:側邊欄自動滾動到當前章節位置
  • 平滑跳轉:點擊章節標題平滑滾動到對應位置

5.2 平板版功能

  • 縮小側邊欄:較窄的側邊欄(220px)
  • 保持所有功能:與桌面版相同的導航功能

5.3 手機版功能

  • 隱藏 TOC:手機寬度不足以顯示TOC
  • 回到頂部按鈕:使用懸浮按鈕讓使用者至少可以快速回到開頭
  • 響應式佈局:文章內容全寬顯示

6. 技術實現細節

6.1 自動滾動算法

  • 使用動態緩衝區域(側邊欄高度的 20%)
  • 智能判斷是否需要滾動
  • 避免微小震盪的閾值保護

6.2 效能優化

  • 手機版不執行 TOC 相關功能
  • 滾動事件節流處理
  • 條件式 DOM 操作

6.3 無障礙設計

  • 正確的 ARIA 標籤
  • 鍵盤導航支援
  • 語義化 HTML 結構