您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
劫持 系统 自动 light 模式
// ==UserScript== // @name 白色模式 light(系统识别版) // @namespace http://tampermonkey.net/ // @version 1.2 // @description 劫持 系统 自动 light 模式 // @author Dahi(AI) // @match *://*/* // @grant none // @license MIT // @run-at document-start // ==/UserScript== (function() { 'use strict'; // 1. 劫持 matchMedia API - 更完善的实现 const originalMatchMedia = window.matchMedia; window.matchMedia = function(mediaQuery) { if (typeof mediaQuery === 'string' && mediaQuery.includes('prefers-color-scheme')) { // 处理所有可能的颜色方案查询 const isLightQuery = mediaQuery.includes('light'); const isDarkQuery = mediaQuery.includes('dark'); const fakeMediaQueryList = Object.create(MediaQueryList.prototype, { matches: { value: isLightQuery || !isDarkQuery, // 如果是light查询或非dark查询返回true writable: false, enumerable: true }, media: { value: mediaQuery, writable: false, enumerable: true }, onchange: { value: null, writable: true, enumerable: true } }); // 添加必要的方法 fakeMediaQueryList.addListener = function() {}; fakeMediaQueryList.removeListener = function() {}; fakeMediaQueryList.addEventListener = function() {}; fakeMediaQueryList.removeEventListener = function() {}; fakeMediaQueryList.dispatchEvent = function() { return true; }; return fakeMediaQueryList; } return originalMatchMedia.apply(this, arguments); }; // 2. 劫持 CSS.supports API - 更全面的处理 const originalCSSSupports = CSS.supports; CSS.supports = function(property, value) { // 处理两种调用方式: supports(property, value) 和 supports(condition) if (arguments.length === 1 && typeof property === 'string') { if (property.includes('prefers-color-scheme')) { return property.includes('light') || !property.includes('dark'); } } else if (arguments.length === 2) { if (property === 'prefers-color-scheme' && value === 'light') { return true; } if (property === 'prefers-color-scheme' && value === 'dark') { return false; } } return originalCSSSupports.apply(this, arguments); }; // 3. 劫持 getComputedStyle - 更安全的实现 const originalGetComputedStyle = window.getComputedStyle; window.getComputedStyle = function(element, pseudoElt) { const styles = originalGetComputedStyle(element, pseudoElt); if (element === document.documentElement || element === document.body) { return new Proxy(styles, { get(target, prop) { if (typeof prop === 'string') { const lowerProp = prop.toLowerCase(); if (lowerProp === 'colorscheme' || lowerProp === 'color-scheme') { return 'light'; } if (lowerProp === 'background-color' && target[prop] === 'rgb(0, 0, 0)') { return 'rgb(255, 255, 255)'; } } return Reflect.get(target, prop); } }); } return styles; }; // 4. 监听动态样式添加 - 更全面的替换 const originalInsertRule = CSSStyleSheet.prototype.insertRule; CSSStyleSheet.prototype.insertRule = function(rule, index) { if (typeof rule === 'string' && rule.includes('prefers-color-scheme')) { rule = rule.replace(/(prefers-color-scheme:\s*)(dark|default)/gi, '$1light'); } return originalInsertRule.call(this, rule, index); }; // 5. 覆盖 localStorage/sessionStorage - 更健壮的实现 const originalSetItem = Storage.prototype.setItem; Storage.prototype.setItem = function(key, value) { if (typeof key === 'string' && typeof value === 'string') { const lowerKey = key.toLowerCase(); if (/(theme|mode|colorscheme|appearance)/i.test(lowerKey)) { value = value.replace(/(dark|default|night)/gi, 'light'); } } return originalSetItem.call(this, key, value); }; // 6. 添加对document.cookie的支持 const originalCookieDescriptor = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie'); Object.defineProperty(document, 'cookie', { get: originalCookieDescriptor.get, set: function(value) { if (typeof value === 'string') { const parts = value.split(';'); const [nameVal, ...options] = parts; const [name, val] = nameVal.split('='); if (name && /(theme|mode|colorscheme)/i.test(name.trim())) { const newVal = val.replace(/(dark|default|night)/gi, 'light'); value = `${name}=${newVal};${options.join(';')}`; } } return originalCookieDescriptor.set.call(this, value); }, configurable: true, enumerable: true }); // 7. 监听DOM变化以处理动态创建的元素 const observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { if (mutation.type === 'attributes' && mutation.attributeName === 'class') { const target = mutation.target; if (target.classList.contains('dark')) { target.classList.remove('dark'); target.classList.add('light'); } } }); }); observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'], subtree: true }); })();