// ==UserScript== // @name Native Image Toggler // @namespace http://tampermonkey.net/ // @version 0.2 // @description 通过原生 UI 控制当前页面图片的显示和隐藏,支持持久化设置 // @author You // @match *://*/* // @grant GM_setValue // @grant GM_getValue // @grant GM_registerMenuCommand // @grant GM_addStyle // @run-at document-start // @downloadURL none // ==/UserScript== (function() { 'use strict'; // 配置常量 const STORAGE_KEY_PREFIX = 'img_toggle_'; const STYLE_ID = 'native-image-toggler-style'; // 获取当前域名的设置键 const hostname = window.location.hostname; const storageKey = STORAGE_KEY_PREFIX + hostname; // 状态:true 表示图片显示(默认),false 表示图片隐藏 // 默认所有网站都是显示的,除非用户手动关闭 let isImagesVisible = GM_getValue(storageKey, true); // CSS 样式:隐藏图片的样式 const hideImageCSS = ` img, image, picture, svg, canvas, video, iframe { opacity: 0 !important; visibility: hidden !important; pointer-events: none !important; } * { background-image: none !important; } /* 排除我们自己的 UI */ #image-toggler-ui, #image-toggler-ui * { opacity: 1 !important; visibility: visible !important; pointer-events: auto !important; background-image: initial !important; } `; // CSS 样式:UI 控件的样式 const uiCSS = ` #image-toggler-ui { position: fixed; top: 10px; right: 20px; z-index: 2147483647; /* Max Z-Index */ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; background-color: rgba(30, 30, 30, 0.8); backdrop-filter: blur(10px); color: #fff; padding: 8px; border-radius: 16px; cursor: pointer; user-select: none; box-shadow: 0 4px 15px rgba(0,0,0,0.3); transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); font-size: 14px; font-weight: 500; display: flex; align-items: center; gap: 8px; border: 1px solid rgba(255, 255, 255, 0.1); opacity: 0.9; } #image-toggler-ui:hover { opacity: 1; transform: translateY(2px); box-shadow: 0 6px 20px rgba(0,0,0,0.4); } #image-toggler-ui.hidden-mode { background-color: rgba(69, 105, 212, 0.9); /* 红色背景警告 */ border-color: rgba(69, 105, 212, 0.5); } #image-toggler-ui.visible-mode { background-color: rgba(69, 105, 212, 0.9); /* 绿色背景正常 */ border-color: rgba(69, 105, 212, 0.5); } #image-toggler-icon { font-size: 16px; line-height: 1; } #image-toggler-text { line-height: 1; } `; // 初始化 function init() { // 尽早应用状态(如果需要隐藏图片) applyState(); // 等待 body 加载完成后创建 UI if (document.body) { setupUI(); } else { document.addEventListener('DOMContentLoaded', setupUI); } // 注册菜单命令作为备用 GM_registerMenuCommand("切换图片显示/隐藏", toggleImages); } function setupUI() { // 防止重复创建 if (document.getElementById('image-toggler-ui')) return; // 添加 UI 样式 GM_addStyle(uiCSS); // 创建 UI createUI(); } // 创建 UI 控件 function createUI() { const div = document.createElement('div'); div.id = 'image-toggler-ui'; div.title = '点击切换当前网站图片显示状态'; div.onclick = toggleImages; document.body.appendChild(div); updateUI(div); } // 更新 UI 显示 function updateUI(element) { const el = element || document.getElementById('image-toggler-ui'); if (!el) return; // 移除旧的类 el.classList.remove('visible-mode', 'hidden-mode'); if (isImagesVisible) { el.innerHTML = '👁️ '; el.classList.add('visible-mode'); el.title = '当前:图片显示。点击隐藏图片'; } else { el.innerHTML = '🚫 '; el.classList.add('hidden-mode'); el.title = '当前:图片隐藏。点击显示图片'; } // 不需要在这里直接设置 backgroundColor,交由 CSS 类处理 el.style.backgroundColor = ''; } // 切换状态 function toggleImages() { isImagesVisible = !isImagesVisible; GM_setValue(storageKey, isImagesVisible); applyState(); updateUI(); } // 应用状态(添加或移除 CSS) function applyState() { let styleEl = document.getElementById(STYLE_ID); // 确保 head 存在,通常在 document-start 时 head 也是存在的(除了极早的情况) // 如果 head 不存在,稍微延时重试 if (!document.head) { setTimeout(applyState, 10); return; } if (!isImagesVisible) { // 如果需要隐藏图片,且样式元素不存在,则添加 if (!styleEl) { styleEl = document.createElement('style'); styleEl.id = STYLE_ID; styleEl.textContent = hideImageCSS; document.head.appendChild(styleEl); } } else { // 如果需要显示图片,且样式元素存在,则移除 if (styleEl) { styleEl.remove(); } } } // 启动 init(); })();