本站当前使用主题(2026-8-28)为Blowfish-修改侧边TOC标题树:支持正文H1 + 仅H1可折叠(默认全部折叠)
Bludit Blowfish主题改造|侧边TOC标题树:支持正文H1 + 仅H1可折叠(默认全部折叠)
适配Blowfish原生JS体系,不改动文章渲染逻辑,仅修改目录生成JS与配套CSS,实现类似Obsidian大纲折叠效果。
改造目标
- 正文Markdown支持多个
# H1一级标题,可正常进入侧边TOC目录树; - 层级缩进:H1顶格加粗,H2/H3/H4逐级缩进;
- 仅H1章节支持折叠展开,H2/H3/H4不可单独折叠;
- 页面加载时所有H1默认折叠;点击H1前方
+/-按钮切换子条目显隐; - 保留原有全部能力:锚点
#悬浮标记、点击目录跳转、scroll-spy滚动高亮、移动端兼容。
修改清单
1. JS两处选择器修改(标题采集)
文件:主题内TOC相关JS
blowfish.js
两处原代码:
var headings = content.querySelectorAll('h2, h3, h4');
全部替换为:
var headings = content.querySelectorAll('h1,h2, h3, h4');
一处是TOC目录生成,一处是标题hover锚点
#生成,两处必须同步修改,否则H1无悬浮锚点。
2. TOC目录构建循环代码(核心折叠逻辑,完整替换)
Array.prototype.forEach.call(headings, function (h) {
const tag = h.tagName.toLowerCase();
var li = document.createElement('li');
li.className = 'toc-item toc-' + tag;
var a = document.createElement('a');
a.href = '#' + h.id;
a.textContent = h.textContent;
a.className = 'toc-link';
if(tag === 'h1'){
const toggleBtn = document.createElement('button');
toggleBtn.className = 'toc-h1-toggle';
toggleBtn.textContent = '+'; // 默认折叠显示加号
toggleBtn.title = '折叠/展开章节';
li.prepend(toggleBtn);
li.appendChild(a);
const subUl = document.createElement('ul');
subUl.className = 'toc-subgroup';
subUl.hidden = true; // 默认全部折叠
li._subUl = subUl;
li.appendChild(subUl);
toggleBtn.onclick = function(e){
e.preventDefault();
const targetUl = li._subUl;
const isHidden = targetUl.hidden;
targetUl.hidden = !isHidden;
toggleBtn.textContent = isHidden ? '−' : '+';
};
ul.appendChild(li);
}else{
li.appendChild(a);
let lastH1li = null;
const siblings = Array.from(ul.children);
for(let i = siblings.length -1; i >=0; i--){
const item = siblings[i];
if(item.classList.contains('toc-h1')){
lastH1li = item;
break;
}
}
if(lastH1li && lastH1li._subUl){
lastH1li._subUl.appendChild(li);
}else{
ul.appendChild(li);
}
}
});
3. TOC完整CSS(替换原有TOC样式,包含层级缩进+折叠按钮)
style.css
/* ========================================
TABLE OF CONTENTS (left sidebar, article view)
======================================== */
.toc-sidebar {
margin-top: var(--space-xl);
position: sticky;
/* 56px = fixed navbar height; extra gap so the ToC doesn't hug it */
top: calc(56px + var(--space-sm));
max-height: calc(100vh - 56px - var(--space-md));
overflow-y: auto;
font-size: var(--font-size-sm);
}
.toc-title {
font-size: var(--font-size-xs);
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--text-muted);
margin-bottom: 0.75rem;
}
.toc-list {
list-style: none;
padding: 0;
margin: 0;
}
.toc-item {
padding: 0.15rem 0;
}
.toc-h1 {
padding-left: 0;
font-weight: 700;
margin-top: 0.4rem;
}
.toc-h2 {
padding-left: 0.75rem;
}
.toc-h3 {
padding-left: 1.5rem;
}
.toc-h4 {
padding-left: 2.25rem;
}
.toc-link {
color: var(--text-muted);
text-decoration: none;
line-height: 1.5;
display: block;
transition: color 0.15s ease;
}
.toc-link:hover {
color: var(--text-primary);
text-decoration: none;
}
.toc-link.active {
color: var(--accent);
font-weight: 600;
text-decoration: none;
}
/* 折叠按钮样式 */
.toc-h1-toggle {
background: transparent;
border: none;
cursor: pointer;
padding: 0 0.2rem 0 0;
font-size: 1em;
color: var(--text-muted);
width:1.2rem;
}
.toc-subgroup {
list-style: none;
padding-left: 0.75rem;
margin: 0.2rem 0;
}
.toc-subgroup .toc-item {
padding:0.15rem 0;
}
行为说明
- 页面载入:所有H1子目录默认折叠,H1前面显示
+; - 点击H1前
+→ 展开下属H2/H3/H4,符号变为−; - 点击
−→ 收起子条目,变回+; - 多个H1互相独立,单独控制,互不干扰;
- 点击H1文字链接,直接跳转到文章内对应H1锚点;
- 滚动页面,scroll-spy依旧自动高亮当前所在目录条目,折叠状态不影响高亮。
回滚方案
- JS:还原目录循环代码,并且把两处
h1,h2,h3,h4改回原始h2,h3,h4; - CSS:删除新增的折叠按钮、toc-h1/toc-h2缩进规则,恢复原始TOC样式。
注意事项
- SEO:页面会出现多个
<h1>,搜索引擎规范不推荐,仅适配个人书写习惯; - 缓存:每次修改后,需要清空Bludit缓存 + 浏览器Ctrl+F5硬刷新;
- 边界:文章无H1时,所有标题直接渲染在根目录,JS不会报错。
测试样例Markdown
# 第一章 测试H1(默认折叠)
## 1.1 二级标题
### 1.1.1 三级标题
#### 1.1.1.1 四级标题
# 第二章 第二个H1(独立折叠)
## 2.1 二级内容
已解决历史问题
- ✅ 原版JS只读取h2-h4,正文H1无法进入目录树;
- ✅ 最初折叠逻辑全局变量覆盖,仅最后一个H1按钮生效;
- ✅ 层级无缩进,目录视觉层次混乱;
- ✅ 新增H1后,hover标题缺少#锚点链接。
后续可扩展:记住页面折叠状态(localStorage),刷新页面保留上次展开/折叠状态。
如果你需要,我可以把这份改造记录合并进之前Blowfish主题优化的复盘MD文档里统一归档。