加载中...

加载中...

本文既是 matery 主题交互视觉功能的完整使用教程,也是 自动化测试靶场。覆盖:代码块增强、图片灯箱、打字机、页面特效、繁简转换、进度条、回顶、打赏、打印。


── 代码与打印 ──

1. 代码块增强

用途

代码块显示语言标签、提供复制/展开/折叠/全屏操作,超长代码自动限高。

配置(主题 _config.ymlcode 块)

code:
  # 代码块语言标签(默认 TEXT,未识别的语言显示 TEXT)
  language:
    enable: true
    default: "TEXT"
  # 复制按钮
  copy_btn: true
  # 展开/折叠按钮(超长代码)
  show_full: true
  # 主动折叠按钮
  shrink: true
  # 代码块最大高度(超过则折叠,带单位字符串)
  height_limit: "450px"

用法

标准 Markdown 代码块即可(自动增强):

```bash
# Bash 示例
echo "Hello Matery"
```

示例(多语言)

# Bash:系统操作
sudo apt update
docker compose up -d
systemctl status nginx
# Python:数据处理
def process(data):
    """处理数据并返回结果"""
    result = [x * 2 for x in data if x > 0]
    return result

print(process([1, -2, 3, 4]))
// JavaScript:异步请求
async function fetchData(url) {
  const response = await fetch(url);
  const data = await response.json();
  console.log("数据:", data);
}
# YAML:配置文件
server:
  host: 0.0.0.0
  port: 8080
  workers: 4
# Python:超长代码示例(超过 450px 高度阈值,触发"展开"按钮)
# 模拟一个简单的博客文章处理流水线
import hashlib
import json
import re
from collections import Counter
from datetime import datetime
from pathlib import Path


def read_posts(directory):
    """读取目录下所有 Markdown 文章"""
    posts = []
    for path in Path(directory).glob("*.md"):
        posts.append(path.read_text(encoding="utf-8"))
    return posts


def extract_front_matter(content):
    """提取 Front-Matter 元数据"""
    match = re.match(r"^---\n(.*?)\n---\n", content, re.DOTALL)
    if not match:
        return {}
    meta = {}
    for line in match.group(1).splitlines():
        if ":" in line:
            key, value = line.split(":", 1)
            meta[key.strip()] = value.strip()
    return meta


def analyze_posts(directory):
    """主分析流程:统计词频、生成摘要、计算字数"""
    all_words = Counter()
    for content in read_posts(directory):
        meta = extract_front_matter(content)
        body = re.sub(r"^---\n.*?\n---\n", "", content, flags=re.DOTALL)
        text = re.sub(r"[#*`>\[\]()]", "", body)
        words = re.findall(r"[\u4e00-\u9fa5]|[a-zA-Z]+", text)
        all_words.update(words)
        word_count = len(words)
        summary = " ".join(words[:20])
        checksum = hashlib.md5(content.encode()).hexdigest()[:8]
        print(f"{meta.get('title', 'untitled')} | {word_count}字 | {checksum}")
        print(f"  摘要: {summary}...")
    print(f"\n共分析 {len(all_words)} 个词汇")
    return all_words


if __name__ == "__main__":
    result = analyze_posts("content/posts")
    top_words = result.most_common(10)
    print("Top 10 高频词:")
    for word, count in top_words:
        print(f"  {word}: {count}")

实现效果

  • 右上角语言标签(bash/python/js/yaml)
  • 复制按钮(点击复制代码)
  • 超长代码显示"展开"按钮
  • 全屏按钮(代码大屏查看)

测试断言:页面含 code-area 标记(≥4 个代码块)。

展开机制(code-area)

代码块限高与展开由 code-area 组件统一处理:

  • 限高code.height_limit(默认 "450px")——超过该高度的代码块自动折叠
  • 展开:折叠态底部显示 scroll-down-bar 展开条,点击后 JS 将容器 maxHeight 设为 scrollHeight(完整显示,不再限高)
  • 横向滚动:代码容器 overflow-x: auto,超宽行横向滚动不换行(配合 code.break: false
  • 全屏code.show_expand: true 提供全屏查看

测试断言:readmode 用例(L11)验证展开后代码完整显示。

Wiki 页行号(prism line-numbers)

Wiki 文档页(layout/wiki.ejs)代码块走 prism 渲染并启用 line-numbers 行号,与文章页代码块增强(toolbar)并存。

测试断言:TC-L15 G5(tools/tests/wiki-prism-integration.test.js,4 断言):tutorial 页加载 / prism-core / 代码块 / line-numbers 行号。


── UI 交互与动效 ──

2. 图片灯箱 lightGallery

用途

文章图片点击放大浏览,支持缩放/翻页/下载。

配置(主题 _config.yml

# 文章图片自动被 articleInit 包装为 .img-item
image_zoom:
  enable: true

图片尺寸注入前置(imgsize.js)

灯箱打开前,主题脚本 scripts/events/lib/imgsize.js 会为页面所有 <img> 注入真实 width/height(防 CLS):

  • 本地图片:同步读取文件尺寸,直接注入
  • 网络图片:命中缓存直接用;命中 CDN→本地映射(image_size_plugin.map_paths)读本地文件;其余异步拉取
  • 缓存持久化image_sizes_cache.json(30 天 TTL,上限 5000 条)
  • 正则兼容:匹配 src 三种形态(带引号/单引号/无引号),兼容 hexo-minify 去引号

该脚本在灯箱绑定之前执行,确保 articleInit() 包装 img → .img-item 时已有尺寸属性,灯箱打开不触发重排。

用法

普通 Markdown 图片即可(自动增强):

![图片描述](/medias_webp/featureimages/1.webp)

示例

灯箱测试图1

灯箱测试图2

实现效果

  • 图片 hover 阴影 + 边框
  • 点击弹出灯箱(全屏 + 缩放 + 翻页)
  • 支持字幕(alt/title 显示)

测试断言:图片被包装为 .img-item,点击弹出 .lg-outer


3. 打字机 Typed

用途

Banner 副标题/文章标题逐字打字动画。

配置(主题 _config.yml

subtitle:
  enable: true
  typed:
    enable: true      # 启用打字机
    loop: true        # 循环轮播
    showCursor: true  # 显示光标
    cursorChar: "_"   # 光标字符
    startDelay: 100   # 启动延迟(ms)
    typeSpeed: 80     # 打字速度(ms/字)
    backSpeed: 50     # 删除速度(ms/字)

post:
  typed:
    enable: true      # 文章标题打字机

实现效果

  • Banner 副标题逐字打出
  • 文章页标题打字效果
  • 光标闪烁 + 循环轮播

测试断言:页面含 #typed.typed-cursor 标记。


4. 页面特效

用途

装饰特效:页面/背景特效(樱花/水波/落叶/雪花/网络/彩带等)与鼠标/点击特效(爱心/星星/烟花等),互斥单选。

配置(主题 _config.ymleffects 块)

effects:
  enable: true          # 总开关
  desktop_only: true    # 是否只在桌面端注入
  page:                 # 页面/背景特效(互斥,选一个)
    default: off        # off | random | 具体 id
    available:
      sakura:        { label: 樱花, lib: sakura }
      ripples:       { label: 水波, lib: ripples }
      leaf:          { label: 落叶, lib: leaf }
      snowdown:      { label: 飘雪, lib: snowdown }
      snowflake:     { label: 雪花, lib: snowflake }
      buble:         { label: 冒泡, lib: buble }
      canvas_nest:   { label: 网络, lib: canvas_nest }
      ribbon:        { label: 彩带, lib: ribbon }
      ribbon_dynamic: { label: 动态彩带, lib: ribbon_dynamic }
  mouse:                # 鼠标/点击特效(互斥,选一个)
    default: off
    available:
      clicklove:     { label: 爱心, lib: clicklove }
      popupText:     { label: 弹出文字, lib: popupText }
      mouseStar:     { label: 星星, lib: star }
      fireworks:     { label: 爆炸, lib: fireworks }

运行时可从右侧悬浮面板切换特效(localStorage matery.effect.page / matery.effect.mouse),无需改代码。

启用条件(desktopGate,desktop_only 开启时)

  • 桌面宽 > BP.fun(1400px,BP 未定义回落 992)
  • localStorage viewCount > 1(防首访即加载)
  • desktop_only: false 时跳过门控(移动端也加载)

实现效果

页面装饰动画,桌面端体验增强,移动端自动关闭(性能)。

测试断言:特效脚本按门控加载(windowWidth > BP.fun)+ 页面/mouse 互斥单选生效。


── 国际化与架构 ──

注:本分区按阅读导航分组,§6–§8 功能上分别属于「UI 交互」「UI 交互」「代码与打印」。

5. 繁简转换

用途

页面繁体/简体一键切换。

配置(主题 _config.yml,2026-08-16 迁移聚合至 preference 段,2026-09-08 全站语言配置统一)

preference:           # 语言类偏好聚合(原 footer.translate 已删除)
  translate:
    enable: true      # 繁简转换开关

实现效果

  • 页脚"繁/简"切换按钮
  • 点击全局转换文字(JS languageToggle,简繁字库映射)
  • localStorage 记忆用户选择(targetEncoding_<host> cookie)

测试断言:页面含 #translateLink 或切换按钮。


6. 阅读进度条 / 返回顶部

用途

阅读进度指示 + 一键回到顶部。

配置(主题 _config.yml

fun_features:
  progressbar:
    enable: true
    height_px: 3
    color: "#29d"

# 返回顶部按钮
backTop:
  enable: true

进度条库配置(libs.js.scrollProgress

进度条基于 ScrollProgress 库实现,库地址在主题 _config.ymllibs.js.scrollProgress 配置(默认走公共 CDN,可换本地 /libs/scrollprogress/scrollProgress.min.js):

libs:
  js:
    scrollProgress: https://lib.baomitu.com/scrollprogress/3.0.2/scrollProgress.min.js

refreshLayout 联动:进度条实例注册为布局回调(Matery.events.registerLayoutCallback),内容动态加载(解密/翻页/下拉加载)后调用 refreshLayout() 会销毁旧实例并重算(避免监听器叠加导致进度计算错误)。

测试断言:TC-L15 G6(tools/tests/core-events-integration.test.js,2 断言):布局回调注册 ≥1 且 refreshLayout() 不抛错。

实现效果

  • 顶部进度条随滚动增长
  • 右下角返回顶部按钮(带平滑滚动)
  • 移动端按钮尺寸自适应

测试断言:页面含 .progress-bar#backTop


7. 打赏弹窗

用途

文章打赏按钮 + 微信/支付宝二维码弹窗。

配置(主题 _config.ymlpost.reward

post:
  reward:
    enable: true
    title: 码字辛苦,打赏作者!
    wechat: /medias_webp/reward/wechat.webp
    alipay: /medias_webp/reward/alipay.webp

文章 front-matter 控制

reward: true    # 开启本文打赏(可选,默认按全局)

实现效果

  • 文章底部"赏"按钮
  • 点击弹出二维码 dialog(支付宝/微信 tabs)
  • 关闭按钮 + 点击遮罩关闭

测试断言:页面含 #reward + 打赏按钮。


8. 打印样式

用途

打印文章时的排版优化。

配置(主题 _config.yml

print:
  enable: true

实现效果

  • 打印时隐藏导航/侧栏/页脚
  • 正文居中 + 优化留白
  • 链接显示 URL

测试断言:CSS 含 @media print 规则。


── 媒体与数据可视化 ──

注:本分区按阅读导航分组,§13–§14 属于「UI 交互」,§15/§18 属于「架构」,§16–§17 属于「UI 交互」。

9. 音乐播放器 APlayer

用途

文章/侧边栏嵌入音乐播放器(MetingJS 解析 + APlayer 播放)。

配置(主题 _config.yml

music:
  enable: true
  server: netease        # netease/tencent/kugou/xiami/baidu
  type: playlist         # song/playlist/album/search/artist
  id: 190133732          # 网易云歌单/歌曲 ID
  fixed: false           # true = 吸底模式
  autoplay: false
  theme: '#42b983'

实现效果

  • 音乐卡片(封面 + 播放控制 + 进度条)
  • 吸底模式(fixed)固定页面底部
  • 暗色模式适配

测试断言:页面含 aplayer 容器标记。


10. 视频播放器 DPlayer

用途

文章内嵌视频播放器(支持 HLS/直播等)。

配置(主题 _config.yml

dplayer:
  enable: true

示例(本地视频)

{% dplayer url=/medias_webp/video/demo.mp4 %}

实现效果

  • 视频播放器(播放/暂停/进度/音量)
  • 支持弹幕(danmaku)

测试断言:页面含 dplayer 容器标记。


11. Bilibili 视频卡片

用途

嵌入 Bilibili 视频(iframe 或卡片)。

配置(主题 _config.yml

bilibili:
  enable: true
  # iframeUrl: //player.bilibili.com/player.html?aid=xxx&bvid=xxx

示例

{% bilibili BV1oa4y1L7mw %}

实现效果

Bilibili 播放器嵌入,可调整尺寸。

测试断言:页面含 bilibili 相关容器标记。


12. ECharts 图表

用途

文章内嵌 ECharts 交互图表。

配置(主题 _config.yml

echarts:
  enable: true

示例

{% echarts '100%' 400 %}
{
  "title": {"text": "示例图表"},
  "xAxis": {"type": "category", "data": ["A", "B", "C"]},
  "series": [{"data": [10, 20, 30], "type": "bar"}]
}
{% endecharts %}

实现效果

ECharts 交互图表(柱状图/折线图/饼图等)。

明暗主题自动切换(2026-09-06 P11 统一)

主题内部全部 ECharts 图表(文章 tag / 词云 / 雷达图 / 文章统计 3 图 / 日历 / 音乐)统一走 Matery.echarts.init(id, option)——监听 theme-changed 事件,切换明暗时自动 dispose + reinit(新主题)+ setOption。容器 CSS 固定高度占位(防 CLS)。

测试断言:页面含 echarts 容器标记 + Matery.echarts 已注册(tools/tests/wordcloud.test.js L2g 验证明暗切换)。


13. AOS 卡片进入动画

用途: 首页瀑布流卡片加载时的进入动画

实现: 新卡片(infScroll 下拉加载)通过 IntersectionObserver 监听 .card,进入视口才加 .card-aos-enter 动画类(fade-in-up,500ms)。不作用于 .article(Masonry 绝对定位,避免重叠)。

配置: AOS 参数在 themes/matery/source/js/boot.js(duration 700ms / delay 100ms)

测试断言:下拉加载后新卡片含 .card-aos-enter,且卡片无重叠(tools/tests/infinite-scroll-aos.test.js)。


14. 悬浮面板(right-floating)

用途

右下角齿轮按钮打开的"偏好设置"面板:字体缩放、语言切换(简/繁)、显示模式(亮/自动/暗)、页面特效开关等,选择保存在 localStorage,跨页面持久化。

配置

面板为纯前端组件(layout/_partial/common/right-floating.ejs + floating-panel.styl),无独立配置开关;面板内各选项与主题既有功能联动(语言走 lang.translate、显示模式走 data-user-color-scheme、特效走 effects 开关)。

用法

  • 点击右下角齿轮按钮(.btn-floating)打开/关闭面板
  • 字体缩放:A+ / A− 步进 0.1,范围 0.85–1.3,作用于根节点 --font-scale CSS 变量;↺ 恢复默认(1.0)
  • 语言区:语言下拉(含国旗,行宽不足时只显国旗)+ 简/繁分段,写入本地偏好并跳转对应语言版
  • 背景区:网页背景 off / 图片 / 视频background.image/video.enable 控制可选项)+ 加载动画样式
  • 选择自动保存到 localStorage(如字体 matery.font-scale、背景 matery.bg),刷新/跨页保持

实现效果

  • 面板默认隐藏,齿轮点击展开(display flex)
  • 字体缩放即时生效并跨页持久化
  • 恢复默认一键还原
  • 面板分区:字体 / 语言 / 显示模式 / 特效 / 背景,各区由对应总开关(effects.enable / background.enable)控制显隐

测试断言:TC-L14(tools/tests/floating-panel-integration.test.js,8 断言,归 release-test L11):面板默认隐藏 / 齿轮打开 / 字体缩放 / 恢复默认等。


15. 事件总线(Matery.events)

用途

主题内部组件通信的统一事件总线,解决"内容动态加载后组件需重新初始化"的问题——解密、翻页、下拉加载等场景触发对应刷新,各组件注册回调即可,无需互相耦合。

API(themes/matery/source/js/events.js

方法作用
Matery.events.registerRefreshCallback(cb)注册全量刷新回调(内容重渲染:MathJax/mermaid/Prism 等)
Matery.events.registerLayoutCallback(cb)注册布局刷新回调(仅重算布局:AOS/Masonry/进度条)
Matery.events.refresh()触发全部 refresh 回调
Matery.events.refreshLayout()触发全部 layout 回调(轻量,不重渲染内容)

用法

// 内容动态加载后需要重渲染 → 全量刷新
Matery.events.registerRefreshCallback(function () { /* 重渲染 */ });
// 仅布局变化(resize/内容高度变化)→ 轻量布局刷新
Matery.events.registerLayoutCallback(function () { /* 重排 */ });
Matery.events.refreshLayout();

实现效果

  • refresh 与 refreshLayout 隔离:全量刷新不重复触发布局,布局刷新不重渲染内容
  • 解密后统一走 refresh(见内容 tag 篇 §14 / 布局篇 §11)

测试断言:TC-L15 G3(tools/tests/core-events-integration.test.js,4 断言):API 存在 / refresh 触发全量 / refreshLayout 触发布局 / 隔离性。


16. Banner 明暗切换

用途

Banner 背景随明暗主题切换联动:theme-changed 事件派发后,body 背景在明暗两套样式间切换;背景模式(图片/视频/关闭)由面板偏好 matery.bg 控制。

配置(主题 _config.yml

背景偏好存 localStorage matery.bg,取值 off | image | video(互斥单选,图片/视频二选一);未设置时回落配置默认 bgDefault。图片/视频背景资源在 _config.yml 对应段配置。

实现效果

  • 切换明暗主题 → color-schema.js dispatch theme-changed → banner/body 背景明暗联动
  • 面板选择背景模式 → 跨页持久化(localStorage matery.bg

测试断言tools/tests/banner-bg.test.js T5:body 背景明暗变化(theme-changed 派发)。


17. 阅读模式与代码全屏(2026-09-06 分离为两个独立功能)

用途

  • 阅读模式(read_mode):文章卡片一键全屏沉浸阅读,隐藏页面其他元素
  • 代码全屏(code-fullscreen):单个代码块容器全屏查看,与阅读模式相互独立(类加在代码容器而非卡片)

用法

  • 阅读模式:文章信息栏(post-info)点击阅读模式按钮(#read_mode)→ 文章卡片 .card-block-fullscreen 全屏;再次点击退出
  • 代码全屏:代码块工具栏点击全屏按钮(.code-area .code-fullscreen)→ 该代码容器 .code-area.code-block-fullscreen 全屏

实现效果

  • 阅读模式进入:卡片 elastic 1s 动画 + 悬浮球延迟淡入(readmode-ball-fade .3s ease .75s both——elastic transform 建立 containing block 会让 fixed 悬浮球跳动,延迟淡入解决)
  • 阅读模式退出:card-block-fullscreen-exit 淡出(scale .98 + opacity 0)→ 220ms 后移除全屏类(防悬浮球跳回)
  • 悬浮球:全屏时 position: fixed; right: 1em; top: 70px; z-index: 10000(top 70 避开导航栏 bottom 64;z 高于导航栏 997)
  • 代码全屏:.code-area.code-block-fullscreen 容器全屏,pre 填满
  • scroll-down-bar 展开pre.style.maxHeight = pre.scrollHeight + 'px'(自动计算完整高度,无内部滚动条、页面滚动);收起 maxHeight=''(恢复 --code-max-height 450px)

测试断言tools/tests/readmode-integration.test.js(L2f PASS=14):阅读模式进入/退出、悬浮球、代码全屏、展开后代码完整显示。


18. JS 加载分层与去 jQuery(2026-09-05 P4/P5)

用途

移除全站 jQuery 依赖(原生 DOM API 重写),并按首屏优先级分层加载脚本,降低首屏阻塞。

配置

  • libs.js.jquery / jqueryUI / jqueryBarrager 均已注释停用(P4/P5 全站去 jQuery 完成;ripples 特效原生重写,contact 页删除)
  • 保留 jqueryPjax(独立库,非全局 jQuery)
  • 分层加载:核心脚本(materialize/masonry/imagesloaded/aos/events/plugins)统一 defer;统计类(umami/busuanzi)async;首屏关键内联脚本同步注入(先于所有 defer 执行)

实现效果

  • 页面不再请求全局 jQuery 库
  • defer 脚本不阻塞首屏解析;内联关键脚本先于 defer 执行,保证依赖顺序

测试断言:页面无全局 jQuery 请求;核心脚本带 defer


⚠️ 已知坑

坑 1:标题编号双重叠加

现象:标题渲染为「1. 1. 概述」(两个编号)。

原因:主题 CSS 自动给 h2–h6 加编号(默认开启),手写编号(如 ## 1. 概述)会叠加。

正确做法:手写编号的页面在 front-matter 加 closeAutoTocNum: true;不手写编号的页面不要加该字段。

本文已正确设置 closeAutoTocNum: true

坑 5:改配置后必须 clean 构建

现象:改了 effects/subtitle.typed/image_zoom 等配置但页面不变。

原因:Hexo 缓存机制不会自动检测配置变更。

正确做法:改配置后必须 npm run clean && npm run build。仅改文章内容(如图片/文字)不需要 clean,增量构建正常工作。


附:交互视觉功能速查表

功能配置键参数要点自动化断言标记
代码块codelanguage/copy_btn/show_fullcode-area
灯箱image_zoom + libs.js.lightgalleryenable.img-item / .lg-outer
打字机subtitle.typed / post.typedloop/showCursor/速度#typed
特效sakura 等 10+ 开关桌面+访问>2 门控windowWidth > BP.fun
繁简lang.translate.enable聚合配置(原 zh_default/footer.translate 删除)#translateLink
进度条progressbarheight/color.progress-bar
回顶backTopenable#backTop
打赏post.rewardwechat/alipay 图#reward
打印printenable@media print
APlayermusicserver/type/idaplayer
DPlayerdplayerurldplayer
BilibilibilibiliiframeUrlbilibili
EChartsechartsJSON 配置echarts
AOS 动画aos(boot.js)duration/delay.card-aos-enter
悬浮面板right-floating(ejs)字体缩放/语言/主题/特效#floating-panel
事件总线Matery.eventsrefresh/refreshLayoutMatery.events
Banner 明暗matery.bg(localStorage)off/image/videobody 背景
Wiki 行号prism line-numberswiki 页代码块.line-numbers
阅读模式#read_mode(post-info 按钮)卡片全屏 + 悬浮球.card-block-fullscreen
代码全屏.code-area .code-fullscreen容器全屏(独立于阅读模式).code-block-fullscreen
JS 加载分层libs.js(jquery 注释停用)核心 defer / 统计 async / 首屏内联同步无全局 jQuery 请求

Hexo主题功能测试-交互视觉篇
发布于
2026年8月7日
许可协议。转载请注明来源
评论
数据加载中 ...
 上一篇

阅读全文

Hexo主题功能测试-Markdown语法篇
Hexo主题功能测试-Markdown语法篇 Hexo主题功能测试-Markdown语法篇
主题 Markdown 语法完整教程与测试:16 个 markdown-it 插件全覆盖(emoji/缩写/脚注/插入/上下标/高亮/任务列表/表格增强/图片尺寸/容器/定义列表/数学公式/中文排版)。每项含用途、语法、示例、实现效果,供自
2026-08-08
下一篇 

阅读全文

Hexo主题功能测试-内容tag篇
Hexo主题功能测试-内容tag篇 Hexo主题功能测试-内容tag篇
主题内容 tag 插件完整教程与测试:note 便签、timeline 时间线、tabs 标签页、label 行内标签、button 按钮、githubCard 卡片、mermaid 图、pdf 嵌入、insertmd 片段、wechat_
2026-08-07