Greasy Fork

来自缓存

Greasy Fork is available in English.

多模式护眼助手

脚本菜单支持多种护眼模式切换,背景与链接颜色配套,支持自定义域名禁用。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         多模式护眼助手
// @version      5.0
// @description  脚本菜单支持多种护眼模式切换,背景与链接颜色配套,支持自定义域名禁用。
// @author       Gemini
// @run-at       document-start
// @match        *://*/*
// @grant        GM_registerMenuCommand
// @grant        GM_setValue
// @grant        GM_getValue
// @namespace http://greasyfork.icu/users/452911
// ==/UserScript==

(function() {
    'use strict';

    // 1. 配置中心:颜色配套方案
    const THEMES = {
        'default':   { name: '豆沙绿', bg: '#C7EDCC', link: '#2E7D32' },
        'parchment': { name: '羊皮纸', bg: '#F4ECD8', link: '#8B4513' },
        'pink':      { name: '樱花粉', bg: '#FDE2E4', link: '#C2185B' },
        'cyan':      { name: '青草蓝', bg: '#DCEFF0', link: '#006064' },
        'warm':      { name: '暖阳黄', bg: '#FAF9DE', link: '#E65100' }
    };

    let currentMode = GM_getValue('currentMode', 'default');
    const currentDomain = window.location.hostname;
    let disabledDomains = GM_getValue('disabledDomains', []);
    let isDisabled = disabledDomains.includes(currentDomain);

    // 2. 注入动态 CSS 变量控制中心
    const styleEl = document.createElement('style');
    styleEl.id = 'eye-protector-core-style';
    // 在 head 还没加载出来时,注入到 documentElement
    (document.head || document.documentElement).appendChild(styleEl);

    function updateCSSVars(modeKey) {
        if (isDisabled) {
            styleEl.textContent = '';
            return;
        }
        const theme = THEMES[modeKey] || THEMES.default;
        styleEl.textContent = `
            :root {
                --eye-bg: ${theme.bg} !important;
                --eye-link: ${theme.link} !important;
            }
            /* 只有被打上标记的元素才会变色 */
            [data-eye-bg="true"] { background-color: var(--eye-bg) !important; background-image: none !important; }
            [data-eye-link="true"] { color: var(--eye-link) !important; text-decoration: none !important; }
        `;
    }

    // 3. 元素扫描与标记引擎
    function scanAndTag() {
        if (isDisabled) return;

        // 获取所有尚未被本脚本扫描过的元素
        const elements = document.querySelectorAll('*:not([data-eye-scanned])');
        
        elements.forEach(el => {
            el.setAttribute('data-eye-scanned', 'true');

            // A. 排除项:视频、图片、画板、图标
            if (el.matches('video, img, canvas, svg, [class*="player"], .icon, .fa')) return;

            // B. 链接处理
            if (el.tagName === 'A') {
                el.setAttribute('data-eye-link', 'true');
            }

            // C. 背景处理:针对原脚本提到的特殊 ID 和 类名 进行强制覆盖
            if (el.matches('DIV#gb-main, DIV.url.clearfix, DIV.nav-bar-v2-fixed, DIV.se-page-hd-content')) {
                el.setAttribute('data-eye-bg', 'true');
                return;
            }

            // D. 智能背景判定:如果是浅色背景,则标记
            const style = window.getComputedStyle(el);
            const bgColor = style.backgroundColor;
            const rgb = bgColor.match(/\d+/g);
            
            if (rgb && rgb.length >= 3) {
                const [r, g, b] = rgb.map(Number);
                // 判定阈值:RGB 均大于 220 通常为白色或近白色背景
                if (r > 220 && g > 220 && b > 220) {
                    el.setAttribute('data-eye-bg', 'true');
                }
            }
        });
    }

    // 4. 注册脚本菜单
    function initMenus() {
        // 开关切换
        GM_registerMenuCommand(isDisabled ? "🟢 开启当前网站护眼" : "🔴 禁用当前网站护眼", () => {
            if (isDisabled) {
                disabledDomains = disabledDomains.filter(d => d !== currentDomain);
            } else {
                disabledDomains.push(currentDomain);
            }
            GM_setValue('disabledDomains', disabledDomains);
            location.reload(); // 涉及域名白名单,建议刷新以重置所有样式
        });

        // 颜色模式切换(无需刷新)
        Object.keys(THEMES).forEach(key => {
            GM_registerMenuCommand("🎨 模式:" + THEMES[key].name, () => {
                currentMode = key;
                GM_setValue('currentMode', key);
                updateCSSVars(key);
                console.log(`已切换至: ${THEMES[key].name}`);
            });
        });
    }

    // 5. 启动逻辑
    updateCSSVars(currentMode);
    initMenus();

    // 持续监听:处理动态加载、瀑布流、弹窗等新元素
    const observer = new MutationObserver(() => {
        scanAndTag();
    });

    // 监听文档变化
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => {
            observer.observe(document.body, { childList: true, subtree: true });
            scanAndTag();
        });
    } else {
        observer.observe(document.body, { childList: true, subtree: true });
        scanAndTag();
    }

    // 兜底:处理某些特殊加载情况
    window.addEventListener('load', scanAndTag);

})();