Tampermonkey

Tampermonkey 汉化脚本

📖 项目介绍

这是一个基于 Tampermonkey 的用户脚本,主要功能是将多个英文 AI 平台和开发工具网站的界面翻译成中文,帮助中文用户更流畅地使用这些工具。

当前仓库包含:

项目主体逻辑位于 汉化脚本.js,翻译词典位于 translations.json,并通过 @resource 机制在脚本初始化时加载。

🌐 支持的网站

🚀 安装方法

方式一:推荐的一键安装

  1. 安装 Tampermonkey 浏览器扩展
  2. 打开脚本直链:
    安装汉化脚本
  3. 在 Tampermonkey 弹出的安装页面中确认安装
  4. 访问支持的网站即可看到中文界面

方式二:从文件安装

  1. 下载 汉化脚本.js 文件
  2. 打开 Tampermonkey 管理面板
  3. 点击”实用工具”标签
  4. 选择文件并导入

方式三:手动开发/调试

  1. 克隆或下载当前仓库
  2. 在 Tampermonkey 中新建脚本并粘贴 汉化脚本.js 内容
  3. 若只调试脚本逻辑,可直接保存脚本并刷新目标页面
  4. 若要联调 translations.json,需要同时修改脚本头部的 @resource translations ... 地址,使其指向你自己的可访问 JSON 资源,再重新安装或更新脚本

✨ 核心特性

⚡ 高性能加载

🧠 智能翻译机制

🔧 技术实现

// 1. 高性能数据结构(Map 哈希查找 + Set 成员检测)
const lowerCaseTranslations = new Map();
const statKeys = new Set(['follower', 'following', 'stars', 'watching', 'forks']);
const skipTags = new Set(['textarea', 'script', 'style', 'noscript']);

// 2. 预编译选择器字符串和正则表达式(避免每次函数调用重建)
const codeSelectorsStr = ['pre', 'code', '.blob-code' /* ... */].join(', ');
const timeRegex = /^(\d+)\s+(year|month|week|day|hour|minute|second)s?\s+ago$/i;
const plClassRegex = /(?:^|\s)pl-[a-z]/;
const zeroWidthRegex = /[\u200B-\u200D\uFEFF]/g;
const whitespaceRegex = /\s+/g;

// 3. 规范化查词(统一空白/大小写/零宽字符)
function normalizeLookupText(text) {
    return text.replace(zeroWidthRegex, '').replace(whitespaceRegex, ' ').trim().toLowerCase();
}

// 4. TreeWalker + NodeFilter 高效遍历(直接裁剪不可翻译子树)
const filter = function (node) {
    if (node.nodeType === Node.ELEMENT_NODE) {
        if (skipTags.has(node.tagName.toLowerCase())) {
            return NodeFilter.FILTER_REJECT; // 跳过整个子树
        }
    }
    return NodeFilter.FILTER_ACCEPT;
};
const walker = document.createTreeWalker(rootNode, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT, filter);

// 5. MutationObserver + requestAnimationFrame + Set 去重批处理
const observer = new MutationObserver(mutations => {
    pendingMutations.push(...mutations);
    if (!rafScheduled) {
        rafScheduled = true;
        requestAnimationFrame(processPendingMutations);
    }
});
// processPendingMutations 内部使用 Set 确保同一节点每帧只处理一次

📝 翻译词条

当前词典已包含 1000+ 常用界面短语与术语翻译,包括:

🔧 自定义翻译

翻译映射表已被提取到独立的 translations.json 文件中,并通过 @resource 机制进行加载。 如需添加或修改翻译词条,可以在 translations.json 文件中进行编辑:

{
    "English Text": "中文翻译",
    "Another Text": "另一个翻译"
}

维护词典时建议优先补充完整界面短语,并保持英文键按字母顺序排序,减少误翻和无意义 diff。

translations.json 会随脚本版本一起通过 @resource 分发。也就是说:

📊 版本信息

🐛 常见问题

Q: 为什么有些文本没有被翻译?
A: 可能是该文本不在翻译映射表中,或者该区域属于脚本刻意保护的结构化内容(如代码块、编辑器、GitHub README、路径面包屑、文件名等)。前者可以通过编辑 translations.json 补充,后者通常不建议直接翻译。

Q: 页面加载时会闪一下吗?
A: 几乎不会。得益于 TreeWalker 子树裁剪和 Map 哈希查找等深度优化,翻译在毫秒级内完成,无需隐藏页面即可实现无感切换。

Q: 会影响页面加载速度吗?
A: 基本不会。脚本利用 TreeWalker API 在底层高效遍历,并通过 requestAnimationFrame 将动态渲染时的海量 DOM 修改进行批处理与去重合并。核心代码预编译了正则,采用了纯净的字典极致查询,大大减轻了重绘压力。

Q: 翻译需要多久完成?
A: 通常都是毫秒级无缝完成。

Q: 支持其他网站吗?
A: 可以。在脚本头部的 @match 部分添加新的网站 URL 即可;如果准备长期维护,也建议同步更新 README 中的支持网站列表。

⚙️ 性能优化

脚本采用了多项性能优化技术:

  1. 提前执行:不等待 DOMContentLoaded,只要 body 存在就开始翻译
  2. 批处理节流:使用 requestAnimationFrameMutationObserver 高频触发的 DOM 更新合并到一帧中集中处理
  3. Set 去重processPendingMutations 内使用 Set 确保同一节点在每帧内只处理一次,消除高频交互时的重复翻译
  4. 预编译常量:正则表达式、选择器字符串、属性名数组、标签跳过集合等全部提升为模块级常量,避免高频函数中反复创建临时对象
  5. 高性能数据结构:翻译字典使用 Map(O(1) 哈希查找),统计关键词和跳过标签使用 Set(O(1) 成员检测)
  6. TreeWalker + NodeFilter 子树裁剪:使用 FILTER_REJECT 直接跳过 script/style/代码块等整个子树,避免遍历成千上万个无用节点
  7. 常量提升:域名判断(isGitHub)等运行时不变量只计算一次,避免逐节点重复字符串匹配
  8. 智能跳过:自动跳过代码块、编辑器、语法高亮等区域,GitHub 场景下使用 closest 预过滤 + 正则精确匹配的两级策略
  9. 变更值校验:DOM 写入前对比新旧值,仅在实际变化时才触发修改,防止与框架的无限循环冲突
  10. SPA / Shadow DOM 支持:延迟翻译与 Shadow Root 监听机制确保 React/Vue 等框架动态渲染内容也能被翻译

🤝 贡献指南

欢迎提交 Issue 和 Pull Request!

📄 许可证

本项目采用 Apache-2.0 许可证开源

📮 联系方式

如有问题或建议,欢迎通过 Issue 反馈