前言
默认归档页解决了“按时间列出文章”,但文章多起来后仍不方便查找。这次重构保留 Hexo 原有归档路由,在其上增加年份折叠、月份分组、搜索、随机阅读和全站编号。
一、为什么必须先关闭归档分页
归档页要按完整年份折叠,就必须一次拿到全部文章。如果 Hexo 每页只交给脚本十篇文章,那么一个年份可能被拆到多页,脚本无法计算准确的年度数量。
因此 _config.yml 中单独关闭主归档分页:
archive_generator: |
这不会关闭首页分页。首页仍可使用:
index_generator: |
两种配置服务于不同目标:主页需要控制首屏长度,归档页需要完整数据。
二、脚本只接管主归档页
Hexo 还会生成 /archives/2026/、/archives/2026/07/ 等子页面。自定义脚本只改造第一页主归档:
const isMainArchive = |
这样,月份统计图等地方跳到具体年月时,仍能使用 Hexo 原生年月归档,不会被整站替换逻辑误伤。
三、文章怎样分成年和月
构建阶段先按日期从新到旧排序,再用两个 Map 分组:
const yearMap = new Map() |
最终数据结构类似:
2026 |
使用 Map 的好处是能保持插入顺序,也能用年份或月份直接找到分组。
四、全站文章编号怎样保持稳定
页面按新到旧展示,但编号希望从最早文章开始累加。脚本先复制一份文章并改成从旧到新,再建立路径到编号的映射:
const chronological = [...posts] |
展示时通过文章路径取回编号,并补足位数:
const serialText = `#${String(serial).padStart(3, '0')}` |
最早的文章是 #001。以后新增文章只会获得更大的编号,历史文章编号不会因为页面排序改变。
五、年份活跃度条怎样生成
每个年份标题右侧有十二格月份活跃度。脚本先创建长度为 12 的数组:
const monthCounts = Array.from( |
随后用该年最高月份作为基准计算透明度:
const max = Math.max(1, ...monthCounts) |
数值通过 CSS 变量传给样式:
<span style="--archive-month-level:0.75"></span> |
CSS 再用这个变量控制颜色深浅。构建阶段负责“算数”,CSS 负责“画出来”。
六、搜索索引为什么写在 HTML 中
每篇文章卡片在生成时,把标题、分类、标签和日期拼成小型搜索索引:
const searchText = `${title} ${category} ${tags} ${date}` |
然后写入:
<article data-archive-search="文章标题 建站笔记 hexo 2026.07.16"> |
用户输入内容时,浏览器无需联网,只在现有 DOM 中匹配。文章数量不大时,这比引入完整搜索库更轻量。
七、过滤必须从文章向上更新
搜索不能只隐藏文章卡片,否则会留下空月份和空年份。正确顺序是:
匹配文章 |
对应代码:
entries.forEach(entry => { |
有搜索词时自动展开命中的年份;清空搜索后恢复为“仅展开最新年份”的初始状态。
八、展开全部与随机阅读
年份折叠使用浏览器原生 <details>。按钮只需要修改 open 属性:
const shouldOpen = !visibleYears.every(year => year.open) |
随机阅读只从当前可见文章中抽取,因此搜索后点击“随便看看”,候选范围会自动缩小:
const candidates = entries.filter(entry => !entry.hidden) |
九、日期为什么要统一时区
Hexo 在不同时区构建时,靠近零点的文章可能被算到前一天或前一个月。本项目明确设置:
timezone: Asia/Shanghai |
GitHub Actions 同样设置:
env: |
源码解析时区和构建环境时区同时固定,年月分组才不会在本地与线上出现差异。
十、封面与分类标签怎样处理
文章有封面时输出懒加载图片;没有封面时显示分类图标占位。标签最多显示两个,多余标签以 +N 表示,避免在手机上把卡片撑得过高。
所有文章标题、分类和标签进入 HTML 前都会转义,内部路径统一通过 urlFor() 加上站点根路径,从而兼容以后把博客部署到子目录的情况。
十一、维护入口
- 分页和时区:
_config.yml - 年月分组、编号和页面结构:
scripts/blog-archives.js - 搜索、折叠与随机阅读:
source/js/blog-archives.js - 归档卡片与响应式:
source/css/blog-archives.css
结语
归档页的核心是先保证数据完整,再按“年 → 月 → 文章”建立层级;浏览器端只负责在已经生成的结构上搜索和交互。






