您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
调整网页下方背景的透明度、颜色遮罩、模糊度,并支持上传本地图片以及自定义元素背景调整。通过Tampermonkey菜单调整设置。
当前为
// ==UserScript== // @name 网页背景调整 // @namespace http://tampermonkey.net/ // @version 1.46 // @description 调整网页下方背景的透明度、颜色遮罩、模糊度,并支持上传本地图片以及自定义元素背景调整。通过Tampermonkey菜单调整设置。 // @author Grey333 // @match *://*/* // @grant GM_setValue // @grant GM_getValue // @license MIT // @grant GM_registerMenuCommand // ==/UserScript== (function() { 'use strict'; // 默认设置 const defaultSettings = { transparency: 1, blur: 0, overlayColor: 'transparent', overlayOpacity: 0, customSelector: '', customTransparency: 0, // 背景初始不透明 customBlur: 0 }; // 加载保存的设置 let settings = JSON.parse(GM_getValue('settings', JSON.stringify(defaultSettings))); let isSelecting = false; // 创建样式元素 const style = document.createElement('style'); style.id = 'background-adjuster-style'; document.head.appendChild(style); // 设置初始 CSS 变量,反转透明度逻辑 document.body.style.setProperty('--base-transparency', 1 - settings.transparency); document.body.style.setProperty('--base-blur', settings.blur === 0 ? 'none' : `blur(${settings.blur}px)`); document.body.style.setProperty('--overlay-color', settings.overlayColor); document.body.style.setProperty('--overlay-opacity', settings.overlayOpacity); document.body.style.setProperty('--custom-transparency', settings.customTransparency); document.body.style.setProperty('--custom-blur', settings.customBlur === 0 ? 'none' : `blur(${settings.customBlur}px)`); // 添加默认白色背景层 const bgLayer = document.createElement('div'); bgLayer.id = 'background-layer'; bgLayer.style.cssText = ` position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; z-index: -2; background: #ffffff; opacity: var(--base-transparency); filter: var(--base-blur); `; document.body.insertBefore(bgLayer, document.body.firstChild); // 添加颜色遮罩层 const overlayLayer = document.createElement('div'); overlayLayer.id = 'overlay-layer'; overlayLayer.style.cssText = ` position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; z-index: -1; background: var(--overlay-color); opacity: var(--overlay-opacity); `; document.body.insertBefore(overlayLayer, document.body.firstChild.nextSibling); // 添加优化后的 CSS 样式 style.textContent = ` body { position: relative; background: transparent !important; } #background-layer { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; z-index: -2; background: #ffffff; opacity: var(--base-transparency); filter: var(--base-blur); } #overlay-layer { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; z-index: -1; background: var(--overlay-color); opacity: var(--overlay-opacity); } body > *:not(#background-layer):not(#overlay-layer):not(#bg-adjuster-panel) { position: relative; z-index: 0; } #bg-adjuster-panel { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: rgba(255, 255, 255, 0.95); border: none; padding: 20px; border-radius: 15px; box-shadow: 0 6px 20px rgba(0,0,0,0.15); z-index: 10000; display: none; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif; width: 280px; max-height: 80vh; overflow-y: auto; } #bg-adjuster-panel label { display: flex; align-items: center; margin: 15px 0; font-size: 14px; color: #333; } #bg-adjuster-panel input[type="range"] { flex: 1; margin: 0 10px; height: 10px; border-radius: 5px; background: #e0e0e0; position: relative; outline: none; cursor: pointer; appearance: none; } #bg-adjuster-panel input[type="range"]::-webkit-slider-runnable-track { height: 10px; border-radius: 5px; } #bg-adjuster-panel input[type="range"]::-moz-range-track { height: 10px; border-radius: 5px; } #bg-adjuster-panel input[type="range"]::-webkit-slider-thumb { appearance: none; width: 18px; height: 18px; background: linear-gradient(135deg, #4a90e2, #357abd); border-radius: 50%; border: 2px solid #fff; cursor: pointer; box-shadow: 0 2px 6px rgba(0,0,0,0.2); margin-top: -4px; } #bg-adjuster-panel input[type="range"]::-moz-range-thumb { width: 18px; height: 18px; background: linear-gradient(135deg, #4a90e2, #357abd); border-radius: 50%; border: 2px solid #fff; cursor: pointer; box-shadow: 0 2px 6px rgba(0,0,0,0.2); } #bg-adjuster-panel .percentage { width: 40px; text-align: right; font-size: 12px; color: #666; } #bg-adjuster-panel .color-btn { width: 24px; height: 24px; border-radius: 50%; border: 2px solid #ddd; cursor: pointer; margin-right: 8px; transition: transform 0.2s, box-shadow 0.2s; } #bg-adjuster-panel .color-btn:hover { transform: scale(1.2); box-shadow: 0 0 4px rgba(0,0,0,0.3); } #bg-adjuster-panel .color-btn:active { transform: scale(1.1); box-shadow: 0 0 6px rgba(0,0,0,0.4); } #bg-adjuster-panel #none-btn { background: transparent; border: 2px dashed #ccc; } #bg-adjuster-panel #yellow-btn { background: #ffff00; } #bg-adjuster-panel #green-btn { background: #00ff00; } #bg-adjuster-panel #custom-color { width: 40px; height: 40px; padding: 0; border: 2px solid #ddd; border-radius: 8px; cursor: pointer; margin-left: auto; } #bg-adjuster-panel button { padding: 6px 12px; cursor: pointer; border-radius: 8px; border: none; background: #f0f0f0; font-size: 12px; transition: background 0.2s; } #bg-adjuster-panel button:hover { background: #e0e0e0; } #bg-adjuster-panel #reset-btn { background: #ff3b30; color: white; } #bg-adjuster-panel #reset-btn:hover { background: #e6392e; } #bg-adjuster-panel #close-btn { background: #4a90e2; color: white; } #bg-adjuster-panel #close-btn:hover { background: #357abd; } #bg-image-label { display: block; margin: 15px 0; font-size: 14px; color: #333; white-space: nowrap; } #bg-image-label input[type="file"] { width: 100%; font-size: 12px; margin-top: 5px; } #overlay-opacity-section { display: none; } #custom-section { display: none; margin-top: 15px; } #custom-input { width: 100%; padding: 5px; font-size: 12px; border: 1px solid #ddd; border-radius: 4px; margin-bottom: 10px; } #custom-btn { background: #6a4ae2; color: white; } #custom-btn:hover { background: #5a3abd; } `; // 创建 UI 面板 const panel = document.createElement('div'); panel.id = 'bg-adjuster-panel'; document.body.appendChild(panel); // UI 面板内容 panel.innerHTML = ` <h3 style="margin: 0 0 20px 0; font-size: 16px; text-align: center; color: #333;">背景调节器</h3> <label>透明度: <input type="range" min="0" max="1" step="0.01" id="transparency-slider" value="${settings.transparency}"><span class="percentage">${Math.round(settings.transparency * 100)}%</span></label> <label>模糊度: <input type="range" min="0" max="20" step="1" id="blur-slider" value="${settings.blur}"><span class="percentage">${Math.round((settings.blur / 20) * 100)}%</span></label> <div id="color-overlay-section"> <label style="display: flex; align-items: center;">颜色遮罩: <button class="color-btn" id="none-btn" title="无"></button> <button class="color-btn" id="yellow-btn" title="黄色"></button> <button class="color-btn" id="green-btn" title="绿色"></button> <input type="color" id="custom-color" value="${settings.overlayColor === 'transparent' ? '#ffffff' : settings.overlayColor}" title="自定义颜色"> </label> </div> <div id="overlay-opacity-section"> <label id="overlay-opacity-label">遮罩透明度: <input type="range" min="0" max="1" step="0.01" id="overlay-opacity" value="${settings.overlayOpacity}"><span class="percentage">${Math.round(settings.overlayOpacity * 100)}%</span></label> </div> <label id="bg-image-label">背景图片:<input type="file" id="bg-image-input" accept="image/*"></label> <button id="custom-btn" style="width: 100%; margin-top: 15px;">自定义</button> <div id="custom-section"> <input type="text" id="custom-input" value="${settings.customSelector}" placeholder="输入或选择CSS选择器"> <label>自定义透明度: <input type="range" min="0" max="1" step="0.01" id="custom-transparency-slider" value="${settings.customTransparency}"><span class="percentage">${Math.round(settings.customTransparency * 100)}%</span></label> <label>自定义模糊度: <input type="range" min="0" max="20" step="1" id="custom-blur-slider" value="${settings.customBlur}"><span class="percentage">${Math.round((settings.customBlur / 20) * 100)}%</span></label> </div> <button id="reset-btn" style="width: 100%; margin-top: 15px;">重置</button> <button id="close-btn" style="width: 100%; margin-top: 10px;">关闭</button> `; // 获取 UI 元素 const transparencySlider = document.getElementById('transparency-slider'); const blurSlider = document.getElementById('blur-slider'); const noneBtn = document.getElementById('none-btn'); const yellowBtn = document.getElementById('yellow-btn'); const greenBtn = document.getElementById('green-btn'); const customColor = document.getElementById('custom-color'); const overlayOpacity = document.getElementById('overlay-opacity'); const overlayOpacityLabel = document.getElementById('overlay-opacity-label'); const overlayOpacitySection = document.getElementById('overlay-opacity-section'); const bgImageInput = document.getElementById('bg-image-input'); const customBtn = document.getElementById('custom-btn'); const customSection = document.getElementById('custom-section'); const customInput = document.getElementById('custom-input'); const customTransparencySlider = document.getElementById('custom-transparency-slider'); const customBlurSlider = document.getElementById('custom-blur-slider'); const resetBtn = document.getElementById('reset-btn'); const closeBtn = document.getElementById('close-btn'); const backgroundLayer = document.getElementById('background-layer'); const overlayLayerElement = document.getElementById('overlay-layer'); const transparencyPercentage = transparencySlider.nextElementSibling; const blurPercentage = blurSlider.nextElementSibling; const overlayOpacityPercentage = overlayOpacity.nextElementSibling; const customTransparencyPercentage = customTransparencySlider.nextElementSibling; const customBlurPercentage = customBlurSlider.nextElementSibling; // 更新设置和 CSS 变量的函数 function updateSettings() { settings.transparency = parseFloat(transparencySlider.value); settings.blur = parseInt(blurSlider.value); settings.overlayColor = customColor.value === '#ffffff' && overlayOpacity.value == 0 ? 'transparent' : customColor.value; settings.overlayOpacity = parseFloat(overlayOpacity.value); settings.customSelector = customInput.value; settings.customTransparency = parseFloat(customTransparencySlider.value); settings.customBlur = parseInt(customBlurSlider.value); document.body.style.setProperty('--base-transparency', 1 - settings.transparency); document.body.style.setProperty('--base-blur', settings.blur === 0 ? 'none' : `blur(${settings.blur}px)`); document.body.style.setProperty('--overlay-color', settings.overlayColor); document.body.style.setProperty('--overlay-opacity', settings.overlayOpacity); document.body.style.setProperty('--custom-transparency', settings.customTransparency); document.body.style.setProperty('--custom-blur', settings.customBlur === 0 ? 'none' : `blur(${settings.customBlur}px)`); GM_setValue('settings', JSON.stringify(settings)); transparencyPercentage.textContent = `${Math.round(settings.transparency * 100)}%`; blurPercentage.textContent = `${Math.round((settings.blur / 20) * 100)}%`; overlayOpacityPercentage.textContent = `${Math.round(settings.overlayOpacity * 100)}%`; customTransparencyPercentage.textContent = `${Math.round(settings.customTransparency * 100)}%`; customBlurPercentage.textContent = `${Math.round((settings.customBlur / 20) * 100)}%`; transparencySlider.style.background = `linear-gradient(to right, #4a90e2 ${settings.transparency * 100}%, #e0e0e0 ${settings.transparency * 100}%)`; blurSlider.style.background = `linear-gradient(to right, #4a90e2 ${(settings.blur / 20) * 100}%, #e0e0e0 ${(settings.blur / 20) * 100}%)`; overlayOpacity.style.background = `linear-gradient(to right, #4a90e2 ${settings.overlayOpacity * 100}%, #e0e0e0 ${settings.overlayOpacity * 100}%)`; customTransparencySlider.style.background = `linear-gradient(to right, #4a90e2 ${settings.customTransparency * 100}%, #e0e0e0 ${settings.customTransparency * 100}%)`; customBlurSlider.style.background = `linear-gradient(to right, #4a90e2 ${(settings.customBlur / 20) * 100}%, #e0e0e0 ${(settings.customBlur / 20) * 100}%)`; // 显示或隐藏遮罩透明度滑块 overlayOpacitySection.style.display = settings.overlayColor === 'transparent' ? 'none' : 'block'; // 应用自定义选择器的背景样式 if (settings.customSelector) { try { const elements = document.querySelectorAll(settings.customSelector); console.log(`Matched elements for "${settings.customSelector}":`, elements.length); elements.forEach((el, index) => { console.log(`Element ${index}:`, el); // 获取原始背景 let originalBg = window.getComputedStyle(el).background; if (!originalBg || originalBg === 'rgba(0, 0, 0, 0)' || originalBg === 'transparent') { originalBg = window.getComputedStyle(el).backgroundColor; } if (!originalBg || originalBg === 'rgba(0, 0, 0, 0)') { console.log(`Element ${index} has no direct background, checking parent...`); let parent = el.parentElement; while (parent && (!originalBg || originalBg === 'rgba(0, 0, 0, 0)' || originalBg === 'transparent')) { originalBg = window.getComputedStyle(parent).backgroundColor; parent = parent.parentElement; } if (!originalBg || originalBg === 'rgba(0, 0, 0, 0)') { originalBg = 'rgba(255, 255, 255, 1)'; // 默认白色 } } console.log(`Original background for element ${index}:`, originalBg); // 处理背景颜色转换为 rgba let rgbaMatch = originalBg.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/i); let bgStyle = originalBg; if (rgbaMatch) { const r = rgbaMatch[1]; const g = rgbaMatch[2]; const b = rgbaMatch[3]; const a = settings.customTransparency; // 透明度从 0(不透明)到 1(透明) bgStyle = `rgba(${r}, ${g}, ${b}, ${1 - a})`; } else if (originalBg.includes('url')) { // 对于图片背景,添加透明度层 bgStyle = `${originalBg}, rgba(0, 0, 0, ${1 - settings.customTransparency})`; } else { bgStyle = `rgba(255, 255, 255, ${1 - settings.customTransparency})`; // 其他情况默认白色 } // 应用背景样式 el.style.background = bgStyle; el.style.backdropFilter = settings.customBlur === 0 ? 'none' : `blur(${settings.customBlur}px)`; el.style.webkitBackdropFilter = settings.customBlur === 0 ? 'none' : `blur(${settings.customBlur}px)`; // 记录原始样式 if (!el.dataset.originalBackground) { el.dataset.originalBackground = originalBg; } if (!el.dataset.originalBackdropFilter) { el.dataset.originalBackdropFilter = window.getComputedStyle(el).backdropFilter || 'none'; } }); } catch (e) { console.error('Invalid CSS selector:', settings.customSelector, e); } } } // 为进度条添加事件监听 transparencySlider.addEventListener('input', updateSettings); blurSlider.addEventListener('input', updateSettings); overlayOpacity.addEventListener('input', updateSettings); customColor.addEventListener('change', updateSettings); customTransparencySlider.addEventListener('input', updateSettings); customBlurSlider.addEventListener('input', updateSettings); customInput.addEventListener('change', updateSettings); // 为颜色按钮添加事件监听 noneBtn.addEventListener('click', () => { customColor.value = '#ffffff'; overlayOpacity.value = 0; updateSettings(); }); yellowBtn.addEventListener('click', () => { customColor.value = '#ffff00'; if (settings.overlayOpacity === 0) overlayOpacity.value = 0.5; updateSettings(); }); greenBtn.addEventListener('click', () => { customColor.value = '#00ff00'; if (settings.overlayOpacity === 0) overlayOpacity.value = 0.5; updateSettings(); }); // 处理背景图片上传 bgImageInput.addEventListener('change', function() { const file = this.files[0]; if (file) { const reader = new FileReader(); reader.onload = function(e) { backgroundLayer.style.backgroundImage = `url(${e.target.result})`; backgroundLayer.style.backgroundSize = 'cover'; backgroundLayer.style.backgroundRepeat = 'no-repeat'; backgroundLayer.style.backgroundColor = 'transparent'; }; reader.readAsDataURL(file); } }); // 自定义按钮功能 customBtn.addEventListener('click', () => { customSection.style.display = customSection.style.display === 'block' ? 'none' : 'block'; if (customSection.style.display === 'block') { isSelecting = true; document.body.style.cursor = 'crosshair'; document.addEventListener('click', handleElementSelection); } else { isSelecting = false; document.body.style.cursor = 'default'; document.removeEventListener('click', handleElementSelection); } }); // 处理元素选择 function handleElementSelection(e) { e.preventDefault(); e.stopPropagation(); const target = e.target; if (panel.contains(target)) return; const selector = generateSelector(target); customInput.value = selector; settings.customSelector = selector; updateSettings(); isSelecting = false; document.body.style.cursor = 'default'; document.removeEventListener('click', handleElementSelection); } // 生成 CSS 选择器 function generateSelector(element) { if (element.id) return `#${element.id}`; if (element === document.body) return 'body'; let path = []; let current = element; while (current && current !== document.body) { let selector = current.tagName.toLowerCase(); if (current.className) { selector += '.' + current.className.trim().split(/\s+/).join('.'); } path.unshift(selector); current = current.parentElement; } return path.join(' > '); } // 重置按钮功能 resetBtn.addEventListener('click', () => { settings = Object.assign({}, defaultSettings); transparencySlider.value = settings.transparency; blurSlider.value = settings.blur; customColor.value = '#ffffff'; overlayOpacity.value = 0; customInput.value = ''; customTransparencySlider.value = settings.customTransparency; customBlurSlider.value = settings.customBlur; document.body.style.setProperty('--base-transparency', 1 - settings.transparency); document.body.style.setProperty('--base-blur', 'none'); document.body.style.setProperty('--overlay-color', 'transparent'); document.body.style.setProperty('--overlay-opacity', 0); document.body.style.setProperty('--custom-transparency', settings.customTransparency); document.body.style.setProperty('--custom-blur', 'none'); backgroundLayer.style.backgroundImage = 'none'; backgroundLayer.style.backgroundColor = '#ffffff'; customSection.style.display = 'none'; isSelecting = false; document.body.style.cursor = 'default'; document.removeEventListener('click', handleElementSelection); // 恢复元素的原始背景样式 if (settings.customSelector) { try { const elements = document.querySelectorAll(settings.customSelector); elements.forEach(el => { el.style.background = el.dataset.originalBackground || ''; el.style.backdropFilter = el.dataset.originalBackdropFilter || 'none'; el.style.webkitBackdropFilter = el.dataset.originalBackdropFilter || 'none'; delete el.dataset.originalBackground; delete el.dataset.originalBackdropFilter; }); } catch (e) { console.error('Error resetting elements:', e); } } GM_setValue('settings', JSON.stringify(settings)); transparencyPercentage.textContent = `${Math.round(settings.transparency * 100)}%`; blurPercentage.textContent = `${Math.round((settings.blur / 20) * 100)}%`; overlayOpacityPercentage.textContent = `${Math.round(settings.overlayOpacity * 100)}%`; customTransparencyPercentage.textContent = `${Math.round(settings.customTransparency * 100)}%`; customBlurPercentage.textContent = `${Math.round((settings.customBlur / 20) * 100)}%`; updateSettings(); }); // 关闭面板 closeBtn.addEventListener('click', () => { panel.style.display = 'none'; document.body.style.cursor = 'default'; document.removeEventListener('click', handleElementSelection); customSection.style.display = 'none'; isSelecting = false; }); // 点击面板外关闭(在非选择模式下) document.addEventListener('click', (e) => { if (!isSelecting && !panel.contains(e.target) && panel.style.display === 'block') { panel.style.display = 'none'; document.body.style.cursor = 'default'; document.removeEventListener('click', handleElementSelection); customSection.style.display = 'none'; } }); // 防止面板内部点击冒泡到外部关闭 panel.addEventListener('click', (e) => { e.stopPropagation(); }); // Tampermonkey 菜单选项 GM_registerMenuCommand('打开背景调节器', () => { panel.style.display = 'block'; }); // 初始化设置 updateSettings(); })();