// ==UserScript== // @name 屏蔽所有网站的图片和图标 (支持 Alt+P 切换及状态保存) // @namespace http://tampermonkey.net/ // @version 1.4 // @description 强制隐藏所有网站图片和图标。按 Alt+P 快捷键可随时开启或关闭,状态全局保存。支持自定义白名单。 // @author Panda-Young // @license MIT // @match *://*/* // @run-at document-start // @grant GM_setValue // @grant GM_getValue // @grant GM_addValueChangeListener // @grant GM_registerMenuCommand // @grant GM_info // @downloadURL https://update.greasyfork.icu/scripts/573319/%E5%B1%8F%E8%94%BD%E6%89%80%E6%9C%89%E7%BD%91%E7%AB%99%E7%9A%84%E5%9B%BE%E7%89%87%E5%92%8C%E5%9B%BE%E6%A0%87%20%28%E6%94%AF%E6%8C%81%20Alt%2BP%20%E5%88%87%E6%8D%A2%E5%8F%8A%E7%8A%B6%E6%80%81%E4%BF%9D%E5%AD%98%29.user.js // @updateURL https://update.greasyfork.icu/scripts/573319/%E5%B1%8F%E8%94%BD%E6%89%80%E6%9C%89%E7%BD%91%E7%AB%99%E7%9A%84%E5%9B%BE%E7%89%87%E5%92%8C%E5%9B%BE%E6%A0%87%20%28%E6%94%AF%E6%8C%81%20Alt%2BP%20%E5%88%87%E6%8D%A2%E5%8F%8A%E7%8A%B6%E6%80%81%E4%BF%9D%E5%AD%98%29.meta.js // ==/UserScript== (function() { 'use strict'; const STORAGE_KEY = 'global_image_block_state'; const WHITELIST_KEY = 'global_image_block_whitelist'; // 双重存储读取逻辑:全局开关状态 let isBlocked = true; try { if (typeof GM_getValue === 'function') { isBlocked = GM_getValue(STORAGE_KEY, true); } else { let localVal = localStorage.getItem(STORAGE_KEY); isBlocked = localVal !== null ? (localVal === 'true') : true; } } catch (e) { console.warn("读取状态失败,采用默认值(开启屏蔽)"); } // --- 白名单匹配逻辑 --- // 读取白名单列表,默认为空数组 let whitelist = typeof GM_getValue === 'function' ? GM_getValue(WHITELIST_KEY, []) : []; // 将通配符规则转换为正则表达式 (例如 *.baidu.com -> ^.*\.baidu\.com$) function ruleToRegex(rule) { let escaped = rule.replace(/[.+?^${}()|[\]\\]/g, '\\$&'); // 转义正则特殊字符,保留 * let regexStr = '^' + escaped.replace(/\*/g, '.*') + '$'; // 将 * 替换为 .* return new RegExp(regexStr, 'i'); // 忽略大小写 } // 检查当前 URL 是否在白名单中 function checkWhitelist() { const currentUrl = window.location.href; for (let rule of whitelist) { if (!rule.trim()) continue; // 如果规则不包含冒号(协议)或斜杠,补全为包含当前域名的通用匹配 let matchRule = rule.includes('/') ? rule : `*://${rule}/*`; if (ruleToRegex(matchRule).test(currentUrl)) { return true; } } return false; } const isWhitelisted = checkWhitelist(); // ��义要注入的全局 CSS const blockStyle = ` img, picture, svg, canvas, video, image { display: none !important; opacity: 0 !important; visibility: hidden !important; width: 0 !important; height: 0 !important; max-width: 0 !important; max-height: 0 !important; } * { background-image: none !important; } [class*="icon" i], [id*="icon" i], [class*="logo" i], [id*="logo" i], [class*="avatar" i], [id*="avatar" i], [class*="img" i], [id*="img" i], [class*="fa-" i], [class^="el-icon" i], [class^="glyphicon" i] { display: none !important; background-image: none !important; } *::before, *::after { background-image: none !important; } `; // 注入或更新样式的函数 function injectOrUpdateStyles() { if (isWhitelisted) return; // 如果在白名单中,永远不注入屏蔽样式 let styleNode = document.getElementById('no-images-strict-style'); if (!styleNode) { styleNode = document.createElement('style'); styleNode.id = 'no-images-strict-style'; styleNode.type = 'text/css'; (document.head || document.documentElement).appendChild(styleNode); } styleNode.textContent = isBlocked ? blockStyle : ''; } // 屏幕中央顶部提示框(Toast) function showToast(message) { let toast = document.getElementById('no-images-toast'); if (!toast) { toast = document.createElement('div'); toast.id = 'no-images-toast'; toast.style.cssText = ` position: fixed; top: 20px; left: 50%; transform: translateX(-50%); padding: 10px 20px; background: rgba(0, 0, 0, 0.75); color: #fff; font-size: 14px; font-family: sans-serif; border-radius: 6px; z-index: 2147483647; pointer-events: none; transition: opacity 0.3s ease; `; document.documentElement.appendChild(toast); } toast.textContent = message; toast.style.opacity = '1'; clearTimeout(toast.timer); toast.timer = setTimeout(() => { toast.style.opacity = '0'; }, 2000); } // 保存状态到本地的函数 function saveState(state) { isBlocked = state; try { if (typeof GM_setValue === 'function') { GM_setValue(STORAGE_KEY, state); } localStorage.setItem(STORAGE_KEY, state); } catch (e) {} } // 初始化执行 injectOrUpdateStyles(); document.addEventListener('DOMContentLoaded', injectOrUpdateStyles); const observer = new MutationObserver(() => { if (!isWhitelisted && !document.getElementById('no-images-strict-style')) { injectOrUpdateStyles(); } }); observer.observe(document.documentElement, { childList: true, subtree: false }); // 监听键盘按键,捕获 Alt + P window.addEventListener('keydown', (e) => { if (e.altKey && e.key.toLowerCase() === 'p') { e.preventDefault(); if (isWhitelisted) { showToast('✅ 当前网站在白名单中,屏蔽已禁用'); return; } let newState = !isBlocked; saveState(newState); // 永久保存新状态 injectOrUpdateStyles(); showToast(newState ? '🚫 已开启:屏蔽所有图片和图标' : '🖼️ 已关闭:恢复显示图片和图标'); } }, true); // 跨标签页状态同步 if (typeof GM_addValueChangeListener === 'function') { GM_addValueChangeListener(STORAGE_KEY, function(name, old_value, new_value, remote) { if (remote && isBlocked !== new_value && !isWhitelisted) { isBlocked = new_value; injectOrUpdateStyles(); showToast(isBlocked ? '🔄 同步开启:屏蔽所有图片' : '🔄 同步关闭:恢复显示图片'); } }); } // --- 可视化白名单配置界面 --- function openConfigUI() { if (document.getElementById('image-block-config-ui')) return; let bg = document.createElement('div'); bg.id = 'image-block-config-ui'; bg.style.cssText = ` position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 2147483647; display: flex; align-items: center; justify-content: center; `; let panel = document.createElement('div'); panel.style.cssText = ` background: #fff; padding: 20px; border-radius: 8px; width: 400px; max-width: 90%; box-shadow: 0 4px 12px rgba(0,0,0,0.2); display: flex; flex-direction: column; gap: 10px; font-family: sans-serif; color: #333; `; let title = document.createElement('h3'); title.textContent = '设置不被屏蔽的网站 (白名单)'; title.style.margin = '0 0 10px 0'; let helpText = document.createElement('p'); helpText.textContent = '每行输入一个规则,支持通配符 * 。例如:\n*.google.com\n*://*.github.com/*'; helpText.style.cssText = 'font-size: 12px; color: #666; margin: 0; white-space: pre-wrap;'; let textarea = document.createElement('textarea'); textarea.rows = 8; textarea.value = (typeof GM_getValue === 'function' ? GM_getValue(WHITELIST_KEY, []) : []).join('\n'); textarea.style.cssText = 'width: 100%; box-sizing: border-box; padding: 8px; border: 1px solid #ccc; border-radius: 4px; resize: vertical; color: #333;'; let btnContainer = document.createElement('div'); btnContainer.style.cssText = 'display: flex; justify-content: flex-end; gap: 10px; margin-top: 10px;'; let cancelBtn = document.createElement('button'); cancelBtn.textContent = '取消'; cancelBtn.style.cssText = 'padding: 6px 12px; border: none; background: #eee; cursor: pointer; border-radius: 4px; color: #333;'; cancelBtn.onclick = () => bg.remove(); let saveBtn = document.createElement('button'); saveBtn.textContent = '保存并刷新'; saveBtn.style.cssText = 'padding: 6px 12px; border: none; background: #007bff; color: #fff; cursor: pointer; border-radius: 4px;'; saveBtn.onclick = () => { let newRules = textarea.value.split('\n').map(r => r.trim()).filter(r => r); if (typeof GM_setValue === 'function') { GM_setValue(WHITELIST_KEY, newRules); } bg.remove(); location.reload(); // 保存后自动刷新页面生效 }; btnContainer.appendChild(cancelBtn); btnContainer.appendChild(saveBtn); panel.appendChild(title); panel.appendChild(helpText); panel.appendChild(textarea); panel.appendChild(btnContainer); bg.appendChild(panel); document.documentElement.appendChild(bg); } // 注册油猴菜单 if (typeof GM_registerMenuCommand === 'function') { GM_registerMenuCommand("⚙️ 配置白名单", openConfigUI); } })();