桌面端侧边栏折叠功能说明
桌面端侧边栏折叠功能说明
功能概述
本博客现已支持桌面端手动折叠侧边栏功能,让你在需要更宽阅读区域时折叠侧边栏,需要导航时再展开。
使用方法
折叠/展开侧边栏
在桌面端(屏幕宽度 ≥ 850px),将鼠标悬停在侧边栏顶部区域时,会显示一个折叠按钮:
- 点击按钮:折叠侧边栏,获得更大的内容区域
- 再次点击:展开侧边栏,恢复导航功能
- 精确触发: 只在侧边栏顶部约 120px 范围内悬停才会显示按钮
- 默认隐藏: 按钮默认不可见,保持界面简洁
自动记忆状态
系统会自动记住你的偏好设置:
- 折叠状态会保存到浏览器的 localStorage
- 下次访问时会自动恢复到你上次的设置
- 清除浏览器缓存会重置此设置
技术实现
1. 折叠按钮
在侧边栏顶部添加了折叠按钮:
1
2
3
<button id="sidebar-collapse" class="btn" aria-label="Collapse Sidebar">
<i class="fas fa-angle-double-left"></i>
</button>
2. CSS 样式
- 触发区域: 在侧边栏顶部设置 120px 高的隐藏触发区域
- 精确触发: 只有鼠标悬停在顶部区域时才显示按钮
- 默认隐藏: 按钮默认透明隐藏,保持界面简洁
- 双重悬停: 触发区域悬停或按钮自身悬停都会显示
- 折叠动画: 折叠时侧边栏向左滑出视野
- 内容扩展: 主内容区域自动扩展占满全屏
- 图标旋转: 按钮图标会旋转 180 度提示状态
3. JavaScript 逻辑
- 监听折叠按钮点击事件
- 切换
data-sidebar-collapsed属性 - 使用 localStorage 保存用户偏好
- 页面加载时恢复上次的状态
4. 响应式设计
- 桌面端(≥ 850px): 显示折叠按钮,支持手动折叠
- 移动端(< 850px): 隐藏折叠按钮,保持原有的自动折叠逻辑
响应式行为
| 屏幕宽度 | 侧边栏行为 |
|---|---|
| ≥ 850px | 固定显示,可手动折叠 |
| < 850px | 自动隐藏,点击菜单按钮展开 |
兼容性
- ✅ Chrome / Edge
- ✅ Firefox
- ✅ Safari
- ✅ 移动端浏览器
注意事项
- 首次使用: 默认状态下侧边栏是展开的
- 状态保存: 状态保存在本地浏览器,不同设备/浏览器需要单独设置
- 清除缓存: 清除浏览器数据会重置折叠状态
- 移动端: 移动端不使用此功能,保持原有的响应式设计
本地测试
访问本地服务器查看效果:http://127.0.0.1:4000/
文件修改清单
_includes/sidebar.html- 添加折叠按钮assets/css/jekyll-theme-chirpy.scss- 添加折叠样式_javascript/modules/components/sidebar.js- 添加折叠逻辑
详细实现步骤
如果你也想在自己的博客中添加类似功能,可以按照以下步骤操作:
步骤 1: 修改侧边栏模板
编辑 _includes/sidebar.html 文件,在侧边栏顶部添加折叠按钮和触发区域:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- The Side Bar -->
<aside aria-label="Sidebar" id="sidebar" class="d-flex flex-column align-items-end">
<!-- Desktop collapse trigger area -->
<div id="sidebar-collapse-trigger" title="悬停显示折叠按钮"></div>
<!-- Desktop collapse button -->
<button id="sidebar-collapse" class="btn" aria-label="Collapse Sidebar" title="折叠侧边栏">
<i class="fas fa-angle-double-left"></i>
</button>
<!-- .sidebar-collapse -->
<header class="profile-wrapper">
<!-- ... 原有代码 ... -->
</header>
<!-- ... 其余代码 ... -->
</aside>
关键点:
sidebar-collapse-trigger: 隐藏的触发区域,只在侧边栏顶部,鼠标悬停时才显示按钮- 按钮 ID 必须为
sidebar-collapse,以便 JavaScript 能够定位 - 使用 Font Awesome 图标
fa-angle-double-left表示折叠 - 添加
aria-label和title提升可访问性
步骤 2: 添加 CSS 样式
编辑 assets/css/jekyll-theme-chirpy.scss 文件,在文件末尾添加以下样式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/* Desktop sidebar collapse functionality */
$sidebar-collapsed-width: 0;
// 添加一个悬停触发区域
#sidebar-collapse-trigger {
display: none;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 120px; // 只在顶部 120px 范围内触发
z-index: 99;
cursor: pointer;
}
// Collapse button styling
#sidebar-collapse {
display: none;
position: absolute;
top: 0.75rem;
right: 0.75rem;
padding: 0.25rem 0.5rem;
background-color: var(--sidebar-btn-bg);
color: var(--sidebar-btn-color);
border: 1px solid var(--sidebar-border-color);
border-radius: 0.375rem;
font-size: 0.875rem;
cursor: pointer;
transition: all 0.3s ease;
z-index: 100;
opacity: 0; // 默认透明隐藏
&:hover {
background-color: var(--sidebar-hover-bg);
transform: scale(1.1);
opacity: 1; // 悬停时显示
}
i {
transition: transform 0.3s ease;
}
}
// Desktop sidebar collapsed state
@media all and (min-width: 850px) {
#sidebar-collapse,
#sidebar-collapse-trigger {
display: block;
}
// 当鼠标悬停在侧边栏顶部区域时显示按钮
#sidebar-collapse-trigger:hover ~ #sidebar-collapse {
opacity: 1;
}
// 按钮自身悬停时也保持显示
#sidebar-collapse:hover {
opacity: 1;
}
body[data-sidebar-collapsed='true'] {
#sidebar {
transform: translateX(-$sidebar-width);
}
#main-wrapper {
margin-left: 0;
}
#sidebar-collapse i {
transform: rotate(180deg);
}
}
}
样式说明:
#sidebar-collapse-trigger: 隐藏的触发区域,只在侧边栏顶部 120px 范围#sidebar-collapse: 折叠按钮的基本样式,包括位置、颜色、过渡动画opacity: 0: 默认透明隐藏,保持界面简洁#sidebar-collapse-trigger:hover ~ #sidebar-collapse: 当鼠标悬停在顶部区域时显示按钮#sidebar-collapse:hover: 按钮自身悬停时也保持显示@media all and (min-width: 850px): 仅在桌面端显示按钮和触发区域body[data-sidebar-collapsed='true']: 折叠状态下的样式规则- 侧边栏向左平移隐藏 (
translateX(-$sidebar-width)) - 主内容区左边距归零,占满全屏
- 图标旋转 180 度变为向右箭头
- 侧边栏向左平移隐藏 (
步骤 3: 实现 JavaScript 逻辑
编辑 _javascript/modules/components/sidebar.js 文件,修改内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/**
* Expand or close the sidebar in mobile screens.
*/
const ATTR_DISPLAY = 'sidebar-display';
const STORAGE_KEY = 'sidebar-collapsed';
class SidebarUtil {
static isExpanded = false;
static toggle() {
if (SidebarUtil.isExpanded === false) {
document.body.setAttribute(ATTR_DISPLAY, '');
} else {
document.body.removeAttribute(ATTR_DISPLAY);
}
SidebarUtil.isExpanded = !SidebarUtil.isExpanded;
}
// Desktop collapse functionality
static initDesktopCollapse() {
const collapseBtn = document.getElementById('sidebar-collapse');
if (!collapseBtn) return;
// Restore saved state
const isCollapsed = localStorage.getItem(STORAGE_KEY) === 'true';
if (isCollapsed) {
document.body.setAttribute('data-sidebar-collapsed', 'true');
}
// Toggle collapse on button click
collapseBtn.addEventListener('click', () => {
const currentState = document.body.getAttribute('data-sidebar-collapsed');
const newState = currentState !== 'true';
if (newState) {
document.body.setAttribute('data-sidebar-collapsed', 'true');
} else {
document.body.removeAttribute('data-sidebar-collapsed');
}
// Save state to localStorage
localStorage.setItem(STORAGE_KEY, newState);
});
}
}
export function sidebarExpand() {
document
.getElementById('sidebar-trigger')
.addEventListener('click', SidebarUtil.toggle);
document.getElementById('mask').addEventListener('click', SidebarUtil.toggle);
// Initialize desktop collapse
SidebarUtil.initDesktopCollapse();
}
逻辑说明:
- 常量定义:
STORAGE_KEY: localStorage 的键名,用于保存状态ATTR_DISPLAY: 移动端侧边栏显示属性
initDesktopCollapse()方法:- 页面加载时从 localStorage 读取上次的状态
- 如果上次是折叠状态,自动应用
data-sidebar-collapsed属性 - 监听按钮点击事件,切换折叠状态
- 保存新状态到 localStorage
sidebarExpand()函数:- 保留原有的移动端折叠功能
- 新增调用
SidebarUtil.initDesktopCollapse()初始化桌面端功能
步骤 4: 重新构建项目
完成修改后,需要重新构建 JavaScript 和 Jekyll 站点:
1
2
3
4
5
6
7
8
# 1. 重新构建 JavaScript
npx rollup -c --bundleConfigAsCjs
# 2. 重新构建网站
bundle exec jekyll build
# 3. 启动本地服务器测试
bundle exec jekyll serve
步骤 5: 测试验证
- 打开浏览器: 访问
http://127.0.0.1:4000/ - 检查按钮: 确认侧边栏右上角显示折叠按钮(双左箭头图标)
- 测试折叠: 点击按钮,侧边栏应该向左滑出,内容区域变宽
- 测试展开: 再次点击,侧边栏滑回,恢复导航
- 测试记忆: 刷新页面,确认状态保持不变
- 响应式测试: 调整浏览器宽度,确认移动端 (< 850px) 按钮隐藏
核心实现原理
1. 状态管理
使用 HTML5 的 data-* 属性管理状态:
- 移动端:
sidebar-display属性(通过body标签控制) - 桌面端:
data-sidebar-collapsed属性(通过body标签控制)
2. CSS Transform 动画
利用 CSS transform 实现平滑的滑入/滑出效果:
1
2
3
4
5
6
7
#sidebar {
transform: translateX(-$sidebar-width); // 隐藏到左侧
}
#main-wrapper {
margin-left: $sidebar-width; // 默认留出侧边栏宽度
}
3. LocalStorage 持久化
使用 localStorage 保存用户偏好:
1
2
3
4
5
// 保存状态
localStorage.setItem('sidebar-collapsed', 'true');
// 读取状态
const isCollapsed = localStorage.getItem('sidebar-collapsed') === 'true';
4. 响应式断点
通过 CSS Media Query 区分桌面端和移动端:
1
2
3
4
5
6
@media all and (min-width: 850px) {
// 桌面端样式
#sidebar-collapse {
display: block;
}
}
技术要点总结
| 技术 | 用途 | 说明 |
|---|---|---|
| HTML Button | 折叠按钮 | 用户交互入口 |
| CSS Transform | 动画效果 | 侧边栏滑入/滑出 |
| CSS Media Query | 响应式 | 区分桌面端/移动端 |
| JavaScript Event | 事件监听 | 点击事件处理 |
| LocalStorage | 状态持久化 | 记住用户偏好 |
| Font Awesome | 图标显示 | 视觉提示 |
常见问题
Q1: 按钮不显示?
A: 检查浏览器宽度是否 ≥ 850px,并确认 CSS 已正确编译。
Q2: 折叠后内容被遮挡?
A: 检查 #main-wrapper 的 margin-left 是否正确设置为 0。
Q3: 状态没有保存?
A: 检查浏览器是否允许 localStorage,或尝试清除缓存后重试。
Q4: 移动端也显示按钮?
A: 确认 CSS Media Query 的断点设置是否正确。
扩展功能建议
如果你有更多需求,可以考虑以下扩展:
- 快捷键支持: 添加键盘快捷键(如
Ctrl + B)快速折叠 - 动画速度配置: 允许用户自定义动画速度
- 多侧边栏支持: 如果博客有多个侧边栏,可以分别控制
- 状态同步: 使用 URL 参数或 Cookie 实现跨设备同步
- 辅助功能: 添加 ARIA 属性,提升无障碍访问体验