// ==UserScript== // @name 网页繁体转简体 (OpenCC) // @name:en Traditional to Simplified Chinese Converter (OpenCC) // @namespace https://greasyfork.org/zh-CN/users/1573766-mayunqing1230 // @version 1.1 // @description 自动将网页上的繁体中文转化为简体中文,支持动态加载的内容,基于准确度极高的 OpenCC 词库。 // @description:en Automatically converts Traditional Chinese characters on webpages to Simplified Chinese. Supports dynamically loaded content and relies on the highly accurate OpenCC dictionary. // @author mayunqing1230 // @homepageURL https://greasyfork.org/zh-CN/scripts/567215-%E7%BD%91%E9%A1%B5%E7%B9%81%E4%BD%93%E8%BD%AC%E7%AE%80%E4%BD%93-opencc // @supportURL https://greasyfork.org/zh-CN/scripts/567215-%E7%BD%91%E9%A1%B5%E7%B9%81%E4%BD%93%E8%BD%AC%E7%AE%80%E4%BD%93-opencc/feedback // @license MIT // @match *://*/* // @grant none // @require https://cdn.jsdelivr.net/npm/opencc-js@1.0.5/dist/umd/full.js // @run-at document-idle // @downloadURL https://update.greasyfork.icu/scripts/567215/%E7%BD%91%E9%A1%B5%E7%B9%81%E4%BD%93%E8%BD%AC%E7%AE%80%E4%BD%93%20%28OpenCC%29.user.js // @updateURL https://update.greasyfork.icu/scripts/567215/%E7%BD%91%E9%A1%B5%E7%B9%81%E4%BD%93%E8%BD%AC%E7%AE%80%E4%BD%93%20%28OpenCC%29.meta.js // ==/UserScript== (function() { 'use strict'; // 检查 OpenCC 是否成功加载 if (typeof OpenCC === 'undefined') { console.error('OpenCC-js 加载失败。'); return; } // 初始化转换器:tw (台湾繁体) -> cn (大陆简体) // 如果常看香港网站,可以将 'tw' 改为 'hk' const converter = OpenCC.Converter({ from: 'tw', to: 'cn' }); // 定义需要忽略的 HTML 标签,防止破坏网页原有功能或修改代码 const ignoreTags = new Set(['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'CODE', 'PRE']); // 核心转换函数:遍历 DOM 树 function convertNode(node) { if (node.nodeType === Node.TEXT_NODE) { const text = node.nodeValue; // 简单正则判断:如果包含非 ASCII 字符再进行转换,避免无意义的性能损耗 if (/[^\x00-\xff]/.test(text)) { node.nodeValue = converter(text); } } else if (node.nodeType === Node.ELEMENT_NODE) { if (ignoreTags.has(node.tagName.toUpperCase())) { return; // 跳过输入框、代码块等特定标签 } // 转换 HTML 属性中的占位符和悬浮提示 if (node.hasAttribute('placeholder')) { node.setAttribute('placeholder', converter(node.getAttribute('placeholder'))); } if (node.hasAttribute('title')) { node.setAttribute('title', converter(node.getAttribute('title'))); } // 递归遍历所有子节点 node.childNodes.forEach(convertNode); } } // 1. 网页首次加载时,转换现有的内容和网页标题 convertNode(document.body); if (document.title) { document.title = converter(document.title); } // 2. 使用 MutationObserver 监听动态加载的新内容 const observer = new MutationObserver((mutations) => { // 暂时断开监听,防止我们在修改 DOM 时触发死循环 observer.disconnect(); mutations.forEach((mutation) => { if (mutation.type === 'childList') { mutation.addedNodes.forEach((node) => { convertNode(node); }); } else if (mutation.type === 'characterData') { const text = mutation.target.nodeValue; if (/[^\x00-\xff]/.test(text)) { mutation.target.nodeValue = converter(text); } } }); // 转换完毕,恢复监听 startObserving(); }); function startObserving() { observer.observe(document.body, { childList: true, // 监听子节点的变动 subtree: true, // 监听所有后代节点 characterData: true // 监听文本节点内容的变动 }); } startObserving(); })();