// ==UserScript== // @name 【网页防挂机】 网页可见性管理 // @namespace https://github.com/realSilasYang // @version 2026-04-14 // @description 在指定域名作用范围内维持页面为可见/活跃状态。内置配置面板,支持动态维护作用域列表、快捷键操作与持久化存储;未启用域名不执行任何逻辑。 // @author 阳熙来 // @match *://*/* // @run-at document-start // @grant GM_getValue // @grant GM_setValue // @grant GM_registerMenuCommand // @grant GM_addStyle // @icon data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGNsYXNzPSJpY29uIiB2aWV3Qm94PSIwIDAgMTAyNCAxMDI0IiB2ZXJzaW9uPSIxLjEiIGRhdGEtZGFya3JlYWRlci1pbmxpbmUtZmlsbD0iIiBkYXRhLXNwbS1hbmNob3ItaWQ9ImEzMTN4LnNlYXJjaF9pbmRleC4wLmkxLjYxYjMzYTgxc0dDRFVlIiB3aWR0aD0iMjU2IiBoZWlnaHQ9IjI1NiI+CiAgPHBhdGggZD0iTTUxNS4wNTE1MiA1MDUuNTIzMmMtMjEuNTA0LTEuNTM2LTQwLjQ0OCAxNC4zMzYtNDEuOTg0IDM1Ljg0IDAgMTMuMzEyIDcuNjggMjUuNiAxOS40NTYgMzIuMjU2djQ5LjE1MmMwIDEwLjc1MiA4LjcwNCAxOS40NTYgMTkuNDU2IDE5LjQ1NiAxMC43NTIgMCAxOS40NTYtOC43MDQgMTkuNDU2LTE5LjQ1NnYtNDkuMTUyYzExLjc3Ni02LjY1NiAxOC45NDQtMTguOTQ0IDE5LjQ1Ni0zMi4yNTYtMS41MzYtMTguOTQ0LTE2Ljg5Ni0zNC4zMDQtMzUuODQtMzUuODR6TTYwOS4yNTk1MiAzOTIuMzcxMmMtMi41Ni01MC4xNzYtNDIuNDk2LTkwLjExMi05Mi42NzItOTIuNjcyLTUzLjc2LTIuNTYtOTguODE2IDM4LjkxMi0xMDEuMzc2IDkyLjY3MnY0NS4wNTZoMTk0LjA0OHYtNDUuMDU2eiIgZmlsbD0iI2Y3NmY1MyIgc3R5bGU9Ii0tZGFya3JlYWRlci1pbmxpbmUtZmlsbDogdmFyKC0tZGFya3JlYWRlci1iYWNrZ3JvdW5kLWY3NmY1MywgIzk0MmUxOSk7IiBkYXRhLWRhcmtyZWFkZXItaW5saW5lLWZpbGw9IiIgZGF0YS1zcG0tYW5jaG9yLWlkPSJhMzEzeC5zZWFyY2hfaW5kZXguMC5pMC42MWIzM2E4MXNHQ0RVZSIgY2xhc3M9InNlbGVjdGVkIj48L3BhdGg+CiAgPHBhdGggZD0iTTk2Ni4xMjM1MiAyOTEuNTA3MmMtMS4wMjQtNy4xNjgtNS4xMi0xNC4zMzYtMTAuNzUyLTE4Ljk0NGwtMjczLjkyLTI0Mi4xNzZjLTkuNzI4LTguMTkyLTIyLjAxNi0xMS4yNjQtMzQuMzA0LTguNzA0aC00NTEuMDcyYy03Mi43MDQtNC4wOTYtMTM1LjY4IDUxLjItMTQwLjI4OCAxMjQuNDE2djY4My4wMDhjNC42MDggNzIuNzA0IDY3LjU4NCAxMjguNTEyIDE0MC4yODggMTI0LjQxNmg2MzEuODA4YzcyLjcwNCA0LjA5NiAxMzUuNjgtNTEuMiAxNDAuMjg4LTEyNC40MTZ2LTUyOC4zODRjMC0zLjA3Mi0wLjUxMi02LjY1Ni0yLjA0OC05LjIxNnogbS02NDcuMTY4IDE4OS45NTJjMC41MTItMjUuMDg4IDIwLjk5Mi00NC41NDQgNDYuMDgtNDQuMDMyaDExLjI2NHYtNDMuNTItMi41NmMxLjUzNi03My4yMTYgNjIuNDY0LTEzMS41ODQgMTM1LjY4LTEzMC4wNDhoMi41NmM3My4yMTYgMCAxMzMuMTIgNTkuMzkyIDEzMy4xMiAxMzMuMTJ2NDMuNTJoMTEuMjY0YzI1LjA4OC0wLjUxMiA0NS41NjggMTguOTQ0IDQ2LjA4IDQ0LjAzMnYxODYuODhjLTAuNTEyIDI1LjA4OC0yMC45OTIgNDQuNTQ0LTQ2LjA4IDQ0LjAzMmgtMjk0LjRjLTI1LjA4OCAwLjUxMi00NS41NjgtMTguOTQ0LTQ2LjA4LTQ0LjAzMnYtMTg3LjM5MnogbTM4Ny41ODQgMzQ1LjZoLTM4OS42MzJjLTExLjI2NCAwLTIwLjQ4LTkuMjE2LTIwLjQ4LTIwLjQ4czkuMjE2LTIwLjQ4IDIwLjQ4LTIwLjQ4aDM4OS42MzJjMTEuMjY0IDAgMjAuNDggOS4yMTYgMjAuNDggMjAuNDhzLTguNzA0IDIwLjQ4LTIwLjQ4IDIwLjQ4eiIgZmlsbD0iIzU4NUU2NiIgc3R5bGU9Ii0tZGFya3JlYWRlci1pbmxpbmUtZmlsbDogdmFyKC0tZGFya3JlYWRlci1iYWNrZ3JvdW5kLTU4NWU2NiwgIzUwNTU1Nyk7IiBkYXRhLWRhcmtyZWFkZXItaW5saW5lLWZpbGw9IiIgZGF0YS1zcG0tYW5jaG9yLWlkPSJhMzEzeC5zZWFyY2hfaW5kZXguMC5pMi42MWIzM2E4MXNHQ0RVZSIgY2xhc3M9IiI+PC9wYXRoPgo8L3N2Zz4K // @license GNU GPLv3 // @downloadURL none // ==/UserScript== (function() { 'use strict'; // === 1. 数据读取与判断 === const STORE_KEY = 'anti_idle_domains'; const currentHost = window.location.hostname; let enabledDomains = GM_getValue(STORE_KEY, []); // 极速拦截:不在白名单内直接停止后续逻辑,实现“0资源占用” const isEnabled = enabledDomains.includes(currentHost); // 注册油猴菜单 GM_registerMenuCommand('⚙️ 生效域名管理', showManagerPanel); // 若未启用,直接退出 if (!isEnabled) return; // === 2. 核心突破逻辑 (仅在白名单域名执行) === const stopEvent = function(e) { e.stopImmediatePropagation(); }; window.addEventListener('blur', stopEvent, true); document.addEventListener('visibilitychange', stopEvent, true); document.addEventListener('webkitvisibilitychange', stopEvent, true); const defineProp = (obj, prop, val) => { try { Object.defineProperty(obj, prop, { get: function() { return val; }, configurable: true }); } catch (e) {} // 静默失败,防止污染控制台 }; defineProp(document, 'visibilityState', 'visible'); defineProp(document, 'hidden', false); defineProp(document, 'webkitVisibilityState', 'visible'); defineProp(document, 'webkitHidden', false); console.log(`[网页防挂机] 当前域名已在列表内,防挂机功能已激活: ${currentHost}`); // === 3. 管理面板 UI 与逻辑 === function showManagerPanel() { if (document.getElementById('anti-idle-manager-mask')) return; let currentDomains = GM_getValue(STORE_KEY, []); let isCurrentEnabled = currentDomains.includes(currentHost); // 注入面板 HTML const mask = document.createElement('div'); mask.id = 'anti-idle-manager-mask'; mask.style.cssText = ` position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: rgba(0, 0, 0, 0.5); z-index: 999999999; display: flex; justify-content: center; align-items: center; font-family: system-ui, -apple-system, sans-serif; backdrop-filter: blur(2px); `; mask.innerHTML = `

🛡️ 防挂机域名列表

当前域名: ${currentHost}
生效域名列表 (每行一个,支持手动编辑):
`; document.body.appendChild(mask); const textarea = document.getElementById('anti-idle-textarea'); textarea.value = currentDomains.join('\n'); // 自动聚焦文本框 textarea.focus(); // 统一的关闭函数 const closePanel = () => { mask.remove(); document.removeEventListener('keydown', handleKeydown); }; // 统一的保存函数 const saveAndReload = () => { let newList = textarea.value.split('\n').map(s => s.trim()).filter(s => s); newList = [...new Set(newList)]; // 数组去重 GM_setValue(STORE_KEY, newList); window.location.reload(); }; // 事件绑定:切换当前域名状态 document.getElementById('anti-idle-toggle-btn').addEventListener('click', function() { let list = textarea.value.split('\n').map(s => s.trim()).filter(s => s); if (isCurrentEnabled) { list = list.filter(d => d !== currentHost); this.innerHTML = '✅ 加入列表'; this.style.background = '#e8f5e9'; this.style.color = '#2e7d32'; } else { if (!list.includes(currentHost)) list.push(currentHost); this.innerHTML = '🚫 移出列表'; this.style.background = '#ffebee'; this.style.color = '#c62828'; } isCurrentEnabled = !isCurrentEnabled; textarea.value = list.join('\n'); }); // 事件绑定:鼠标点击按钮或遮罩层关闭 document.getElementById('anti-idle-close-btn').addEventListener('click', closePanel); mask.addEventListener('click', (e) => { if (e.target === mask) closePanel(); }); // 事件绑定:鼠标点击保存 document.getElementById('anti-idle-save-btn').addEventListener('click', saveAndReload); // 事件绑定:全局快捷键监听 const handleKeydown = (e) => { // Esc 退出 if (e.key === 'Escape') { e.preventDefault(); closePanel(); } // Ctrl+S 或 Cmd+S 保存 else if ((e.ctrlKey || e.metaKey) && e.key === 's') { e.preventDefault(); saveAndReload(); } }; document.addEventListener('keydown', handleKeydown); } })();