Hexo + Butterfly 搭建教程 05:本站自定义组件合集
前言
完成基础配置后,本站没有直接修改 Butterfly 的主题包,而是持续通过 source/css、source/js 和 Hexo 生成脚本增加功能。
这些组件有些只是普通的前端代码,可以移植到任何网站;有些会读取 Hexo 生成的数据;还有一些专门依赖 Butterfly 的 DOM 和 PJAX。了解这种差异,可以避免把“使用了 Hexo”和“只能在 Hexo 中运行”混为一谈。
一、组件与框架的关系
可以把组件分成三类:
| 类型 | 特征 | 迁移难度 |
|---|---|---|
| 通用前端组件 | 只需要 HTML、CSS、JavaScript | 低 |
| Hexo 数据组件 | 读取文章、分类或生成阶段数据 | 中 |
| Butterfly 增强组件 | 依赖 Butterfly DOM、主题切换或 PJAX | 中到高 |
例如音乐播放器本身不要求 Hexo;分类磁贴的动画也不要求 Hexo,但当前脚本读取 Butterfly 分类页生成的类名,因此迁移时需要替换数据入口。
二、全局音乐播放器
本站音乐播放器位于页面左下角,主要功能包括:
- 网易云歌单加载
- 播放与暂停
- 上一首和下一首
- 音量调节
- 顺序、随机、列表循环和单曲循环
- 侧边收起与悬浮展开
- 预先检查下一首是否可播放
- PJAX 页面跳转后保持全局可用
它的主体是原生 JavaScript 和 CSS,并不是只有 Hexo 才能使用。迁移到其他网站时需要:
- 在全局布局中加载播放器资源。
- 提供歌单数据接口。
- 把 PJAX 生命周期替换为目标框架的路由生命周期。
需要注意,用户拥有网易云 VIP 并不代表访客可以通过第三方网页播放器获得完整 VIP 权限。VIP、版权限制、地区限制和接口状态都由音乐服务决定。
完整实现已经在独立教程中介绍:
三、分类全息磁贴
Butterfly 默认分类总览主要是文字链接。本站在不修改主题模板的情况下,把它增强为:
- 双列响应式磁贴
- 分类名称和文章数量
- 独立图标、说明和色相
- 指针跟随高光
- 轻微 3D 倾斜
- 暗色主题适配
- 奇数卡片居中
- 手机端单列
实现方式是读取:
1 | |
然后保留原始链接,重新组织内部结构。JavaScript 失败时仍会显示 Butterfly 默认分类列表,这是一种渐进增强。
完整教程:
四、标签星座
标签页适合表达内容之间的联系,而不只是标签名称列表。本站将标签展示成具有空间层次的星座节点:
- 标签数量映射为视觉权重
- 明暗主题分别配色
- 悬浮显示强调效果
- 手机端降低动态并保持可点击区域
它当前读取 Butterfly 标签页 DOM,因此属于 Butterfly 增强组件。若迁移到独立主题,可以直接在模板阶段输出同样的数据结构,省去浏览器中的二次重组。
五、技术参考与朋友友链
友链页面被拆分为:
1 | |
技术参考采用一行三张的紧凑卡片,悬浮时放大并展示更多信息;朋友区域使用更完整的头像与介绍卡。
这个设计解决了两类链接语义不同的问题:
- 技术资料强调访问效率。
- 朋友链接强调人物与关系。
实现仍是普通 HTML、CSS 和 JavaScript,可迁移性较高。
六、全局命令面板搜索
原生搜索入口适合传统博客,但内容和组件增加后,需要一个更接近桌面应用的全局入口。
本站命令面板提供:
- 固定在右上角的入口
- 键盘快捷键
- 搜索文章标题、简介和标签
- 快速打开分类、标签、日志和友链
- 支持 PJAX 导航
- 手机端独立排版
它的数据来自 Hexo 生成的搜索索引,因此搜索界面是通用组件,数据层则属于 Hexo 集成。
有了全局检索后,原来的搜索按钮可以隐藏,避免两个入口功能重复。
七、首页单列与双列切换
访客可以选择:
- 一行一篇:更适合阅读摘要
- 一行两篇:更适合快速浏览
组件需要处理:
- 奇数篇文章的最后一张卡片
- 不同卡片高度
- 手机端强制单列
- 用户选择的本地保存
- 页面切换后的布局恢复
用户偏好可以保存到:
1 | |
这个功能与 Butterfly 首页 DOM 有一定耦合,但核心网格逻辑可以迁移。
八、随机封面图池与固定映射
这是一个 Hexo 生成阶段组件,而不是浏览器组件。
工作流程:
1 | |
只有图片被移出图池时,对应文章才会重新分配。这样既保留随机性,又避免每次部署后封面变化。
文章页首图和首页封面被分离处理,防止竖图在标题横幅中被严重裁切。
这个功能依赖 Hexo 的生成钩子,迁移到其他静态生成器时需要改写构建插件,但算法本身可以保留。
九、页脚运行状态与旅行者一号
页脚目前组合了:
- 博客运行时间
- 旅行者一号任务信息
- 简短状态文字
- “暗淡蓝点”格言
状态规则被简化为:
1 | |
部署脚本写入最后部署时间,浏览器脚本计算当前状态。这比根据随机事件或访问动作推测站长状态更加明确。
旅行者一号数据会定期更新,不应该把一个永远不变的距离数字直接写死在页面中。
十、自动更新日志
本站部署流程不仅执行 hexo deploy,还在 npm 脚本中加入:
- 更新外部数据
- 检查项目变化
- 收集待发布日志
- 标记部署时间
- 生成网站
- 执行部署
更新日志不会每次自动发布为文章,而是先积累在本地记录中。等变化足够多时,再统一整理到日志页面。
这说明:
1 | |
和:
1 | |
可能具有不同效果。前者执行 package.json 中定义的完整流程,后者只调用 Hexo 部署器。
十一、文章简介悬浮详情
首页卡片为了整齐通常会限制摘要行数,但长简介会被截断。本站在摘要确实溢出时提供悬浮详情:
- 普通状态保持固定高度
- 鼠标悬浮显示完整文本
- 没有溢出时不创建提示
- 手机端不依赖 hover
这类功能要先比较元素的 scrollHeight 和 clientHeight,不能给所有摘要无条件显示重复提示。
十二、时钟组件为什么被停用
页首时钟曾显示日期、时间和状态,但它过于显眼,会与首页标题和背景争夺视觉中心。因此组件代码被保留,默认注入被注释。
这是组件设计中很重要的一点:
功能完整不等于应该启用。
博客首先是阅读空间。一个组件如果无法改善导航、阅读或氛围,就应该降低存在感,甚至暂时关闭。
时钟的完整制作方式仍保留在教程中:
十三、如何决定下一个组件
可以用四个问题筛选:
- 它解决了真实问题吗?
- 原生配置是否已经能够完成?
- 手机端和无障碍状态怎样处理?
- 主题升级后维护成本有多高?
优先开发:
- 改善导航和搜索的组件
- 减少重复操作的自动化
- 强化文章组织方式的组件
- 与网站内容气质一致的轻量氛围效果
谨慎添加:
- 大面积跟随鼠标动画
- 自动播放音频
- 多个功能重复的悬浮按钮
- 阻挡正文的弹窗
- 依赖不稳定第三方接口的核心功能
下一篇将讨论这些定制内容怎样逐步脱离 Butterfly,形成结构清晰的独立 Hexo 主题。
参考资料与声明
本文中的组件均来自本站实际使用或保留的实现。部分结构与文字由 AI 协助整理。






