Lumin Blog 沉浸阅读模式:一键专注阅读
📌 概述
沉浸阅读模式是 Lumin Blog 的一项阅读体验优化功能,允许读者一键切换到无干扰的阅读环境。开启后,导航栏、侧边栏、TOC 目录、面包屑、页脚等非内容元素全部隐藏,文章内容居中展示,帮助读者专注于文字本身。
本功能基于纯 CSS 状态切换 + ES Module 实现,无需任何第三方依赖。
🎯 一、功能说明
交互方式
| 操作 | 效果 |
|---|---|
| 点击右下角绿色书本图标 | 进入沉浸模式 |
| 再次点击红色 ✕ 图标 | 退出沉浸模式 |
按 Esc 键 | 退出沉浸模式 |
| 刷新页面 | 记住上次状态(localStorage) |
沉浸模式效果
- 隐藏导航栏 — 顶部导航栏平滑上移消失
- 隐藏侧边栏 — 右侧侧边栏和 TOC 目录完全移除
- 隐藏面包屑 — 页面顶部面包屑导航隐藏
- 隐藏页脚 — 底部页脚区域隐藏
- 内容居中 — 文章内容以 860px 宽度居中展示
- 按钮重排 — 返回顶部和评论按钮下移至底部,阅读模式按钮上移
🏗️ 二、实现架构
文件结构
1assets/js/modules/reading-mode.js ← 切换逻辑模块
2assets/js/main.js ← 模块注册入口
3assets/css/main.css ← 按钮样式 + body.reading-mode 状态样式
4layouts/partials/toolbar.html ← 按钮 HTML
核心原理
沉浸阅读模式的核心是 body.reading-mode CSS 类:
- 点击按钮 →
document.body.classList.toggle('reading-mode') - CSS 选择器
body.reading-mode .site-header等控制各元素显隐 - 导航栏使用
transform: translateY(-100%)平滑滑出 - 侧边栏使用
display: none !important直接移除 .layout-grid使用grid-template-columns: 1fr变为单列居中
💻 三、代码详解
3.1 按钮 HTML(toolbar.html)
按钮位于右下角浮动工具栏,与返回顶部、评论跳转按钮垂直排列:
1<button id="reading-mode-toggle" class="reading-mode-toggle"
2 aria-label="沉浸阅读" title="沉浸阅读">
3 <!-- 书本图标:进入阅读模式 -->
4 <svg class="rm-icon rm-icon--read" ...>
5 <path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/>
6 <path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/>
7 </svg>
8 <!-- 关闭图标:退出阅读模式 -->
9 <svg class="rm-icon rm-icon--exit" ...>
10 <path d="M18 6L6 18"/><path d="M6 6l12 12"/>
11 </svg>
12</button>
双图标通过 CSS .reading-mode-toggle.active 切换显隐。
3.2 按钮样式(main.css)
1.reading-mode-toggle {
2 position: fixed;
3 bottom: 11rem; /* 评论按钮上方 */
4 right: 1.5rem;
5 width: 46px;
6 height: 46px;
7 background: linear-gradient(135deg, #059669, #10b981); /* 绿色 */
8 border-radius: 50%;
9 /* ... */
10}
11.reading-mode-toggle.active {
12 background: linear-gradient(135deg, #dc2626, #ef4444); /* 红色 */
13}
3.3 页面状态样式(main.css)
1body.reading-mode .site-header {
2 transform: translateY(-100%); /* 导航栏滑出 */
3 opacity: 0;
4 pointer-events: none;
5}
6body.reading-mode .layout-grid {
7 grid-template-columns: 1fr !important; /* 单列居中 */
8 max-width: 860px;
9 margin: 0 auto;
10}
11body.reading-mode aside.sidebar,
12body.reading-mode .post-toc-sidebar {
13 display: none !important; /* 侧边栏移除 */
14}
15body.reading-mode .breadcrumb { display: none; }
16body.reading-mode .site-footer { display: none; }
3.4 切换逻辑(reading-mode.js)
1export function init() {
2 toggleBtn = document.getElementById('reading-mode-toggle');
3
4 // 仅在文章详情页显示
5 isArticlePage = !!document.querySelector('.post-content, .article-content, .single-content');
6 if (!isArticlePage) return;
7
8 // 点击切换
9 toggleBtn.addEventListener('click', function() {
10 var isActive = document.body.classList.toggle('reading-mode');
11 toggleBtn.classList.toggle('active', isActive);
12 localStorage.setItem('lumin-reading-mode', isActive ? '1' : '0');
13 if (isActive) window.scrollTo({ top: 0, behavior: 'smooth' });
14 });
15
16 // Esc 退出
17 document.addEventListener('keydown', function(e) {
18 if (e.key === 'Escape' && document.body.classList.contains('reading-mode')) {
19 // 退出逻辑...
20 }
21 });
22
23 // 恢复上次状态
24 if (localStorage.getItem('lumin-reading-mode') === '1') {
25 document.body.classList.add('reading-mode');
26 toggleBtn.classList.add('active');
27 }
28}
📐 四、右下角按钮布局
从下到上垂直排列,形成统一的浮动工具栏:
| 位置 | 按钮 | 颜色 | bottom |
|---|---|---|---|
| 最下 | 🚀 返回顶部 | 紫色渐变 | 2rem |
| 中间 | 💬 评论跳转 | 蓝色 | 6.5rem |
| 最上 | 📖 沉浸阅读 | 绿色/红色 | 11rem |
沉浸模式开启后,返回顶部和评论按钮下移,阅读按钮上移,避免视觉拥挤。
🔑 五、设计决策
为什么用 body.reading-mode 而非独立页面?
- 状态切换即时 — 无需页面跳转,CSS 过渡动画流畅
- 状态可持久化 — localStorage 记住用户偏好
- 实现简洁 — 纯 CSS 控制显隐,JS 只负责切换 class
- Esc 退出 — 键盘友好,符合用户直觉
为什么只在文章页显示?
列表页、归档页等内容密度高的页面不适合沉浸模式。通过检测 .post-content 等选择器,确保按钮只在有长文阅读需求的页面出现。
为什么内容宽度 860px?
860px 在 16px 基础字号下约容纳 95 字符/行,适合中文博客的阅读场景。中文排版因字符宽度一致,行长度比英文更可控,稍宽的设置能减少换行频率,提升阅读流畅度。
🛠️ 六、自定义配置
如需调整沉浸模式的内容宽度,修改 main.css 中的 max-width 值:
1body.reading-mode .layout-grid {
2 max-width: 860px; /* 修改此值,推荐范围 680-860px */
3}
如需调整按钮显隐的滚动阈值,修改 reading-mode.js:
1var show = scrollTop > 200; // 滚动超过 200px 后显示按钮
留言评论
期待你的想法评论加载中