您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
【多站点独立配置】智能状态同步 + 跨Tab保活控制(每个网站独立设置)+AJAX心跳
当前为
// ==UserScript== // @name 网页保活助手 // @namespace http://tampermonkey.net/ // @version 5.2.0 // @description 【多站点独立配置】智能状态同步 + 跨Tab保活控制(每个网站独立设置)+AJAX心跳 // @author DavidZhang53 // @match *://*/* // @grant GM_registerMenuCommand // @grant GM_getValue // @grant GM_setValue // @grant GM_addStyle // @grant GM_xmlhttpRequest // @license MIT // ==/UserScript== (function () { 'use strict'; // 生成带网站标识的存储键 const currentSite = window.location.hostname; const getSiteKey = (key) => `${currentSite}_${key}`; // 配置存储(每个网站独立) const CONFIG = { keepAliveEnabled: GM_getValue(getSiteKey('keepAliveEnabled'), true), keepAliveInterval: GM_getValue(getSiteKey('keepAliveInterval'), 300), inactivityLimit: GM_getValue(getSiteKey('inactivityLimit'), 600), forceRefreshEnabled: GM_getValue(getSiteKey('forceRefreshEnabled'), false), lastActivity: GM_getValue(getSiteKey('lastActivity'), Date.now()) }; // 运行时状态 let state = { refreshTimer: null, keepAliveTimer: null, pendingRefresh: false }; // 视觉样式 GM_addStyle(` #control-container { position: fixed; top: 0; left: 0; width: 50px; height: 50px; z-index: 1000000; cursor: pointer; } #control-container:hover #control-panel { display: block !important; } #control-panel { display: none; position: absolute; left: 0; top: 50px; background: rgba(255,255,255,0.98); border-radius: 8px; padding: 15px; box-shadow: 0 4px 10px rgba(0,0,0,0.2); width: 320px; z-index: 1000001; } #refresh-warning { position: fixed; bottom: 20px; right: 20px; background: lightyellow; color: #000; padding: 20px 30px; border-radius: 10px; font-size: 18px; z-index: 999999; text-align: center; box-shadow: 0 4px 15px rgba(0,0,0,0.3); } .status-indicator { position: fixed; bottom: 10px; right: 10px; padding: 5px 10px; border-radius: 3px; font-size: 12px; z-index: 999998; } .active-status { background: #28a745; color: white; } .inactive-status { background: #dc3545; color: white; } `); // 控制面板 function createControlPanel() { const container = document.createElement('div'); container.id = 'control-container'; const panel = document.createElement('div'); panel.id = 'control-panel'; panel.innerHTML = ` <h3 style="margin:0 0 15px 0;">保活控制中心 - ${currentSite}</h3> <label style="display:block; margin:10px 0;"> <input type="checkbox" id="keepAliveEnabled" ${CONFIG.keepAliveEnabled ? 'checked' : ''}> 启用智能保活 </label> <label style="display:block; margin:10px 0;"> 保活间隔(秒): <input type="number" id="keepAliveInterval" value="${CONFIG.keepAliveInterval}" style="width:80px;"> </label> <label style="display:block; margin:10px 0;"> 无操作超时(秒): <input type="number" id="inactivityLimit" value="${CONFIG.inactivityLimit}" style="width:80px;"> </label> <label style="display:block; margin:10px 0;"> <input type="checkbox" id="forceRefreshEnabled" ${CONFIG.forceRefreshEnabled ? 'checked' : ''}> 强制全页刷新 </label> <div style="margin-top:15px; color:#666; font-size:12px;"> 当前状态: <span id="statusText">检测中...</span> </div> `; container.appendChild(panel); document.body.appendChild(container); const inputs = panel.querySelectorAll('input, select'); inputs.forEach(input => { input.addEventListener('change', handleSettingChange); }); updateStatusDisplay(); } // 设置变更处理 function handleSettingChange(e) { const target = e.target; switch(target.id) { case 'keepAliveEnabled': CONFIG.keepAliveEnabled = target.checked; GM_setValue(getSiteKey('keepAliveEnabled'), target.checked); if (!target.checked) stopKeepAlive(); break; case 'keepAliveInterval': CONFIG.keepAliveInterval = Math.max(10, parseInt(target.value) || 300); GM_setValue(getSiteKey('keepAliveInterval'), CONFIG.keepAliveInterval); resetKeepAlive(); break; case 'inactivityLimit': CONFIG.inactivityLimit = Math.max(60, parseInt(target.value) || 600); GM_setValue(getSiteKey('inactivityLimit'), CONFIG.inactivityLimit); break; case 'forceRefreshEnabled': CONFIG.forceRefreshEnabled = target.checked; GM_setValue(getSiteKey('forceRefreshEnabled'), target.checked); break; } updateStatusDisplay(); } // 核心保活逻辑 function checkActivityState() { const now = Date.now(); const elapsed = now - CONFIG.lastActivity; const isInactive = elapsed > CONFIG.inactivityLimit * 1000; if ((document.hidden || isInactive) && !state.keepAliveTimer) { startKeepAlive(); } else if (!document.hidden && !isInactive && state.keepAliveTimer) { stopKeepAlive(); } } function startKeepAlive() { if (!CONFIG.keepAliveEnabled) return; performKeepAlive(); state.keepAliveTimer = setInterval(() => { performKeepAlive(); }, CONFIG.keepAliveInterval * 1000); } function performKeepAlive() { GM_xmlhttpRequest({ method: 'HEAD', url: window.location.href, onload: (res) => { if (CONFIG.forceRefreshEnabled && shouldForceRefresh()) { scheduleForceRefresh(); } }, onerror: (err) => { if (CONFIG.forceRefreshEnabled && shouldForceRefresh()) { scheduleForceRefresh(); } } }); } function shouldForceRefresh() { return document.hidden || (Date.now() - CONFIG.lastActivity > CONFIG.inactivityLimit * 1000); } // 刷新控制相关 function scheduleForceRefresh() { if (state.pendingRefresh) return; state.pendingRefresh = true; showRefreshWarning(); state.refreshTimer = setTimeout(() => { location.reload(); }, CONFIG.keepAliveInterval * 1000); document.addEventListener('visibilitychange', handleVisibilityChange); } function handleVisibilityChange() { if (!document.hidden && state.pendingRefresh) { cancelRefresh(); stopKeepAlive(); } } function cancelRefresh() { clearTimeout(state.refreshTimer); state.refreshTimer = null; state.pendingRefresh = false; const warning = document.getElementById('refresh-warning'); warning && warning.remove(); } function showRefreshWarning() { const warning = document.createElement('div'); warning.id = 'refresh-warning'; warning.innerHTML = ` <div>系统即将自动刷新</div> <div style="font-size:14px; margin-top:8px;"> 倒计时: <span id="refreshCountdown">${CONFIG.keepAliveInterval}</span>秒 </div> `; document.body.appendChild(warning); startCountdown(); } function startCountdown() { const countdownEl = document.getElementById('refreshCountdown'); let remaining = CONFIG.keepAliveInterval; const timer = setInterval(() => { remaining--; countdownEl.textContent = remaining; if (remaining <= 0) clearInterval(timer); }, 1000); } // 辅助功能 function stopKeepAlive() { clearInterval(state.keepAliveTimer); state.keepAliveTimer = null; cancelRefresh(); } function resetKeepAlive() { stopKeepAlive(); checkActivityState(); } function updateStatusDisplay() { const statusText = document.querySelector('#statusText'); if (!statusText) return; statusText.textContent = state.keepAliveTimer ? `工作中 (间隔:${CONFIG.keepAliveInterval}秒)` : '待机中 (检测无操作状态)'; } // 事件监听 function initEventListeners() { ['mousemove', 'keydown', 'click'].forEach(event => { document.addEventListener(event, () => { CONFIG.lastActivity = Date.now(); GM_setValue(getSiteKey('lastActivity'), CONFIG.lastActivity); if (!document.hidden) { cancelRefresh(); stopKeepAlive(); } checkActivityState(); }); }); document.addEventListener('visibilitychange', () => { checkActivityState(); updateStatusDisplay(); }); setInterval(() => { checkActivityState(); updateStatusDisplay(); }, 1000); } // 初始化 function init() { if (document.body) { createControlPanel(); initEventListeners(); checkActivityState(); } else { window.addEventListener('DOMContentLoaded', init); } } init(); })();