Greasy Fork is available in English.
替换网页的字体
当前为
// ==UserScript==
// @name 替换网页字体
// @author ai
// @version 2.1
// @match *://*/*
// @run-at document-start
// @grant GM_addStyle
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_registerMenuCommand
// @grant GM_unregisterMenuCommand
// @description 替换网页的字体
// @namespace http://greasyfork.icu/users/22620
// ==/UserScript==
(function() {
'use strict';
const CONFIG_KEYS = {
FONT: 'config_font',
EXCLUSIONS: 'config_exclusions',
ENABLED: 'config_enabled'
};
const DEFAULT_CONFIG = {
font: '微软雅黑',
exclusions: 'i, [class*="ico"], [class*="emoji"]',
enabled: true
};
class FontManager {
constructor() {
this.config = this.loadConfig();
this.applyFont();
this.initMenu();
}
loadConfig() {
return {
font: GM_getValue(CONFIG_KEYS.FONT, DEFAULT_CONFIG.font),
exclusions: GM_getValue(CONFIG_KEYS.EXCLUSIONS, DEFAULT_CONFIG.exclusions),
enabled: GM_getValue(CONFIG_KEYS.ENABLED, DEFAULT_CONFIG.enabled)
};
}
saveConfig(key, value) {
const oldValue = GM_getValue(key);
if (oldValue !== value) {
GM_setValue(key, value);
this.config = this.loadConfig();
this.applyFont();
}
}
generateCSS() {
if (!this.config.enabled) return '';
const { font, exclusions } = this.config;
let notSelector = '';
if (exclusions) {
notSelector = exclusions.split(',')
.map(s => s.trim())
.filter(Boolean)
.map(s => `:not(${s})`)
.join('');
}
return `*${notSelector} { font-family: ${font} !important; }`;
}
async applyFont() {
// 移除旧样式
if (this.styleElement) {
this.styleElement.remove();
}
if (!this.config.enabled) return;
// 注入初始字体
this.styleElement = GM_addStyle(this.generateCSS());
console.log(`⏱️ 阶段一:注入初始字体: ${this.config.font}`);
// 等待网页字体加载后更新
await document.fonts?.ready;
const webFonts = this.getWebFonts();
const finalFonts = webFonts ? `${this.config.font}, ${webFonts}` : this.config.font;
this.styleElement.textContent = this.generateCSS();
console.log(`✅ 阶段二:最终字体: ${finalFonts}`);
}
getWebFonts() {
if (!document.fonts) return '';
const fonts = new Set();
document.fonts.forEach(font => {
if (font.family) fonts.add(`"${font.family}"`);
});
return [...fonts].join(', ');
}
initMenu() {
this.menuCommands = new Map();
this.updateMenu();
}
updateMenu() {
// 清除旧菜单
this.menuCommands.forEach(id => GM_unregisterMenuCommand(id));
this.menuCommands.clear();
// 注册新菜单
this.menuCommands.set('toggle', GM_registerMenuCommand(
this.config.enabled ? '❌ 禁用字体效果' : '✅ 启用字体效果',
() => this.toggleEnabled()
));
this.menuCommands.set('font', GM_registerMenuCommand('🖋️ 配置字体名称',
() => this.promptConfig('font', '请输入新的字体名称')
));
this.menuCommands.set('exclusions', GM_registerMenuCommand('🚫 配置排除元素列表',
() => this.promptConfig('exclusions', '请输入新的排除元素选择器')
));
this.menuCommands.set('reset', GM_registerMenuCommand('🗑️ 恢复默认设置',
() => this.resetToDefault()
));
}
toggleEnabled() {
this.saveConfig(CONFIG_KEYS.ENABLED, !this.config.enabled);
this.updateMenu();
}
promptConfig(type, promptText) {
const key = CONFIG_KEYS[type.toUpperCase()];
const current = this.config[type];
const newValue = prompt(`${promptText}:\n(用逗号分隔,例如: ${type === 'font' ? '"微软雅黑", system-ui' : 'i, [class*="ico"]'})`, current);
if (newValue?.trim()) {
this.saveConfig(key, newValue.trim());
}
}
resetToDefault() {
if (confirm('确定要将所有配置恢复为默认值吗?')) {
Object.entries(CONFIG_KEYS).forEach(([key, storageKey]) => {
const type = key.toLowerCase();
GM_setValue(storageKey, DEFAULT_CONFIG[type]);
});
this.config = this.loadConfig();
this.applyFont();
this.updateMenu();
}
}
}
new FontManager();
})();