1. 文件落位

性质 位置
站点专属功能 source/js/ + source/css/
加载后执行一次 source/js/inject/
必须改模板结构 themes/chengic/

优先前两项。动主题意味着后续升级要手动合并。

2. HTML 进入页面

独立页面:source/<名字>/index.md,front-matter 指定 type: page,正文写 HTML。

构建期注入:不改模板,往页面塞脚本。

1
hexo.extend.injector.register('body_end', '<script src="/js/xxx.js" defer></script>', 'default');

运行期插入:脚本自己建节点。注意后插入的 <a> 不被 pjax 拦截,需补绑。

3. 样式作用域

一页一个前缀(.tt-、.mg-、.ab2-)。脚本入口先判锚点,没有就退出:

1
2
const root = document.querySelector('.mg-form');
if (!root) return;

4. 生命周期

1
2
3
4
5
6
7
function init() { /* 绑定 */ }

document.addEventListener('DOMContentLoaded', init);
document.addEventListener('pjax:complete', function () {
teardown();
init();
});

只 init 不 teardown,监听器会累积,表现为一次点击触发多次。

5. 版本号

1
<script defer src="/js/my-feature.js?v=20261105a"></script>

页面级写在 front-matter 或 md,全站写在 _config.chengic.yml 的 inject 段。

6. 适配

  • 颜色用变量(--glass-bg、--font-color、--ucard-bd),暗色自动跟随
  • 手机至少验三件事:宽度溢出、点击区 ≥44px、吸顶遮挡
  • prefers-reduced-motion 下关闭动画

7. 自检清单

  1. 首页、文章页、新页面均正常
  2. 从首页 pjax 进入新页面,功能仍可用
  3. 暗色可读
  4. 375px 宽无横向滚动
  5. 重复点击不重复触发
  6. ?v= 已推
  7. 控制台无报错
  8. 改过 .pug 已重启 hexo server

8. 示例:回到顶部

1
2
3
4
5
6
7
8
9
10
// source/js/inject/back-top.js
(function () {
if (document.getElementById('bt-btn')) return;
const btn = document.createElement('button');
btn.id = 'bt-btn';
btn.textContent = '↑';
document.body.appendChild(btn);
btn.addEventListener('click', () => window.scrollTo({ top: 0, behavior: 'smooth' }));
window.addEventListener('scroll', () => btn.classList.toggle('show', window.scrollY > 400));
})();
1
2
3
4
5
6
7
#bt-btn {
position: fixed; right: 24px; bottom: 96px;
width: 44px; height: 44px; border-radius: 50%;
opacity: 0; pointer-events: none; transition: opacity .2s;
}
#bt-btn.show { opacity: 1; pointer-events: auto; }
@media (prefers-reduced-motion: reduce) { #bt-btn { transition: none; } }

9. 登记

改动写入 docs/站点改动总览.md:症状、根因、文件与行、验证方式、回滚。