Greasy Fork is available in English.
全局修改字体
当前为
// ==UserScript==
// @name 全局字体
// @author gemini
// @version 1.04
// @match *://*/*
// @run-at document-start
// @grant GM_addStyle
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_registerMenuCommand
// @namespace http://greasyfork.icu/users/22620
// @description 全局修改字体
// ==/UserScript==
(function() {
'use strict';
// --- 默认配置项 ---
const DEFAULT_FONT = '"MiSans"';
// 默认排除常见的图标、符号和特殊元素
const DEFAULT_EXCLUSIONS = 'i, [class*="ico"], [class*="fa"]';
// --- GM 存储的 Key ---
const STORAGE_KEY_FONT = 'config_my_new_font';
const STORAGE_KEY_EXCLUSIONS = 'config_icon_exclusion_selectors';
// --- 内部变量 (由配置加载) ---
let MY_NEW_FONT;
let ICON_EXCLUSION_SELECTORS_ARRAY;
let phaseOneStyleElement = null;
// --- GM 配置函数 ---
/**
* 从 GM 存储中加载配置,如果没有则使用默认值。
*/
const loadConfig = () => {
// 从存储中读取字体
MY_NEW_FONT = GM_getValue(STORAGE_KEY_FONT, DEFAULT_FONT);
// 从存储中读取排除选择器字符串
const storedExclusionsString = GM_getValue(STORAGE_KEY_EXCLUSIONS, DEFAULT_EXCLUSIONS);
// 将字符串分割成数组,并去除空格和空元素
ICON_EXCLUSION_SELECTORS_ARRAY = storedExclusionsString
.split(',')
.map(s => s.trim())
.filter(s => s.length > 0);
console.log(`⚙️ 已加载配置: 字体: ${MY_NEW_FONT}, 排除项数量: ${ICON_EXCLUSION_SELECTORS_ARRAY.length}`);
};
// --- 菜单命令实现 ---
/**
* 弹出配置字体名称的对话框。
*/
const configFontName = () => {
const currentFont = GM_getValue(STORAGE_KEY_FONT, DEFAULT_FONT);
const newFont = prompt(
'请输入新的字体名称 (用逗号分隔,例如: "MiSans", system-ui, sans-serif)',
currentFont
);
if (newFont !== null) {
GM_setValue(STORAGE_KEY_FONT, newFont.trim());
alert('字体名称已保存!请刷新页面以应用新设置。');
}
};
/**
* 弹出配置排除元素列表的对话框。
*/
const configExclusionList = () => {
const currentExclusions = GM_getValue(STORAGE_KEY_EXCLUSIONS, DEFAULT_EXCLUSIONS);
const newExclusions = prompt(
'请输入新的排除元素选择器 (用逗号分隔,用于保护图标字体等,例如: i, [class*="ico"])',
currentExclusions
);
if (newExclusions !== null) {
GM_setValue(STORAGE_KEY_EXCLUSIONS, newExclusions.trim());
alert('排除列表已保存!请刷新页面以应用新设置。');
}
};
/**
* 恢复所有配置为默认值。
*/
const resetConfig = () => {
if (confirm('确定要将字体配置和排除列表都恢复为默认值吗?')) {
GM_setValue(STORAGE_KEY_FONT, DEFAULT_FONT);
GM_setValue(STORAGE_KEY_EXCLUSIONS, DEFAULT_EXCLUSIONS);
alert('配置已恢复为默认值!请刷新页面以应用。');
}
};
/**
* 注册配置菜单命令。
*/
const registerMenu = () => {
GM_registerMenuCommand('🖋️ 配置字体名称', configFontName);
GM_registerMenuCommand('❌ 配置排除元素列表', configExclusionList);
GM_registerMenuCommand('🗑️ 恢复默认设置', resetConfig);
};
// --- CSS 注入逻辑 (不变) ---
const generateCSS = (fontFamily) => {
const ICON_EXCLUSION_SELECTOR_STRING = ICON_EXCLUSION_SELECTORS_ARRAY
.map(selector => `:not(${selector})`)
.join('');
return `
/* 全局选择器,排除图标和特殊符号元素 */
*${ICON_EXCLUSION_SELECTOR_STRING} {
font-family: ${fontFamily} !important;
}
`;
};
const injectPhaseOneCSS = (newFontFamily) => {
const cssContent = generateCSS(newFontFamily);
phaseOneStyleElement = GM_addStyle(cssContent);
console.log(`⏱️ 阶段一:立即注入初始字体: ${newFontFamily}`);
};
const runPhaseTwo = async (newFontFamily) => {
try {
await document.fonts.ready;
const protectedFontNames = new Set();
document.fonts.forEach(fontFace => {
protectedFontNames.add(`"${fontFace.family.replace(/"/g, '')}"`);
});
const protectedFontFamily = Array.from(protectedFontNames).join(', ');
let finalFontFamily = protectedFontFamily
? `${newFontFamily}, ${protectedFontFamily}`
: `${newFontFamily}`;
const cssContentFinal = generateCSS(finalFontFamily);
// 尝试更新已注入的 <style> 元素
if (phaseOneStyleElement && typeof phaseOneStyleElement.textContent !== 'undefined') {
phaseOneStyleElement.textContent = cssContentFinal;
console.log("✅ 阶段二:全局字体已最终更新并保护原有字体:", finalFontFamily);
} else {
// 备用:再次注入
GM_addStyle(cssContentFinal);
console.log("✅ 阶段二:全局字体已最终更新并保护原有字体 (通过再次注入):", finalFontFamily);
}
} catch (error) {
console.error("⚠️ 字体加载或识别过程中出错,将保持初始字体设置:", error);
}
};
// --- 脚本主执行流程 ---
// 1. 注册 Tampermonkey 菜单命令
registerMenu();
// 2. 加载用户配置
loadConfig();
// 3. 运行字体注入的两个阶段
injectPhaseOneCSS(MY_NEW_FONT);
runPhaseTwo(MY_NEW_FONT);
})();