护眼模式

简单有效的全网通用护眼模式、夜间模式、暗黑模式

目前为 2021-07-16 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name 护眼模式
  3. // @version 1.1.6
  4. // @author X.I.U
  5. // @description 简单有效的全网通用护眼模式、夜间模式、暗黑模式
  6. // @match *://*/*
  7. // @exclude *://v.qq.com/*
  8. // @exclude *://*.iqiyi.com/*
  9. // @exclude *://*.youku.com/*
  10. // @exclude *://*.mgtv.com/*
  11. // @exclude *://tv.cctv.com/*
  12. // @icon https://i.loli.net/2021/03/07/rdijeYm83pznxWq.png
  13. // @grant GM_registerMenuCommand
  14. // @grant GM_unregisterMenuCommand
  15. // @grant GM_getValue
  16. // @grant GM_setValue
  17. // @grant GM_notification
  18. // @noframes
  19. // @license GPL-3.0 License
  20. // @run-at document-start
  21. // @namespace https://github.com/XIU2/UserScript
  22. // @supportURL https://github.com/XIU2/UserScript
  23. // @homepageURL https://github.com/XIU2/UserScript
  24. // ==/UserScript==
  25.  
  26. (function() {
  27. var menu_ALL = [
  28. ['menu_runDuringTheDay', '白天保持开启 (比晚上亮一点点)', '白天保持开启', true],
  29. ['menu_autoRecognition', '排除自带暗黑模式的网页 (beta)', '排除自带暗黑模式的网页 (beta)', true],
  30. ['menu_darkModeType', '点击切换模式', '点击切换模式', 1],
  31. ['menu_customMode', '自定义当前模式', '自定义当前模式', '80|70'],
  32. ['menu_customMode1', '自定义模式 1', '自定义模式 1', '80|70'],
  33. ['menu_customMode2', '自定义模式 2', '自定义模式 2', '80|20|70|30'],
  34. ['menu_customMode3', '自定义模式 3', '自定义模式 3', '80']
  35. ], menu_ID = [], websiteList = ['rarbgprx.org','fitgirl-repacks.site','masquerade.site','www.gamersky.com'];
  36. for (let i=0;i<menu_ALL.length;i++){ // 如果读取到的值为 null 就写入默认值
  37. if (GM_getValue(menu_ALL[i][0]) == null){GM_setValue(menu_ALL[i][0], menu_ALL[i][3])};
  38. }
  39. registerMenuCommand();
  40. addStyle();
  41.  
  42.  
  43. // 注册(不可用)脚本菜单
  44. function registerMenuCommand() {
  45. if (menu_ID.length > menu_ALL.length){ // 如果菜单ID数组多于菜单数组,说明不是首次添加菜单,需要卸载所有脚本菜单
  46. for (let i=0;i<menu_ID.length;i++){
  47. GM_unregisterMenuCommand(menu_ID[i]);
  48. }
  49. }
  50. for (let i=0;i<menu_ALL.length;i++){ // 循环注册(不可用)脚本菜单
  51. menu_ALL[i][3] = GM_getValue(menu_ALL[i][0]);
  52. if (menu_ALL[i][0] === 'menu_darkModeType') {
  53. if (menu_ALL[i][3] > 3){ // 避免在减少 raw 数组后,用户储存的数据大于数组而报错
  54. menu_ALL[i][3] = 1;
  55. GM_setValue('menu_darkModeType', menu_ALL[i][3]);
  56. }
  57. menu_ID[i] = GM_registerMenuCommand(`🔄 [ ${menu_ALL[i][3]} ] ${menu_ALL[i][1]}`, function(){menu_toggle(`${menu_ALL[i][3]}`,`${menu_ALL[i][0]}`)});
  58. } else if (menu_ALL[i][0] === 'menu_customMode') {
  59. GM_setValue('menu_customMode', menu_ALL[i][3]);
  60. menu_ID[i] = GM_registerMenuCommand(`✅ ${menu_ALL[i][1]}`, function(){menu_customMode()});
  61. } else if (menu_ALL[i][0] === 'menu_customMode1') {
  62. GM_setValue('menu_customMode1', menu_ALL[i][3]);
  63. } else if (menu_ALL[i][0] === 'menu_customMode2') {
  64. GM_setValue('menu_customMode2', menu_ALL[i][3]);
  65. } else if (menu_ALL[i][0] === 'menu_customMode3') {
  66. GM_setValue('menu_customMode3', menu_ALL[i][3]);
  67. } else {
  68. menu_ID[i] = GM_registerMenuCommand(`🌝 [ ${menu_ALL[i][3]?'√':'×'} ] ${menu_ALL[i][1]}`, function(){menu_switch(`${menu_ALL[i][3]}`,`${menu_ALL[i][0]}`,`${menu_ALL[i][2]}`)});
  69. }
  70. }
  71. menu_ID[menu_ID.length] = GM_registerMenuCommand('💬 反馈 & 建议', function () {window.GM_openInTab('https://github.com/XIU2/UserScript#xiu2userscript', {active: true,insert: true,setParent: true});window.GM_openInTab('https://gf.qytechs.cn/zh-CN/scripts/412212/feedback', {active: true,insert: true,setParent: true});});
  72. }
  73.  
  74.  
  75. // 自定义当前模式
  76. function menu_customMode() {
  77. let newMods, tip, defaults, name;
  78. switch(menu_value('menu_darkModeType')) {
  79. case 1:
  80. tip = '自定义 [模式 1],修改后立即生效 (部分网页可能需要刷新)~\n格式:亮度 (白天)|亮度 (晚上)\n默认:80|70(均为百分比 1~100,不需要 % 符号)';
  81. defaults = '80|70';
  82. name = 'menu_customMode1';
  83. break;
  84. case 2:
  85. tip = '自定义 [模式 2],修改后立即生效 (部分网页可能需要刷新)~\n格式:亮度 (白天)|暖色 (白天)|亮度 (晚上)|暖色 (晚上)\n默认:80|20|70|30(均为百分比 1~100,不需要 % 符号)';
  86. defaults = '80|20|70|30';
  87. name = 'menu_customMode2';
  88. break;
  89. case 3:
  90. tip = '自定义 [模式 3],修改后立即生效 (部分网页可能需要刷新)~\n格式:反色\n默认:80(均为百分比 50~100,不需要 % 符号)';
  91. defaults = '80';
  92. name = 'menu_customMode3';
  93. break;
  94. }
  95. newMods = prompt(tip, GM_getValue(`${name}`));
  96. if (newMods === '') {
  97. GM_setValue(`${name}`, defaults);
  98. registerMenuCommand(); // 重新注册(不可用)脚本菜单
  99. } else if (newMods != null) {
  100. GM_setValue(`${name}`, newMods);
  101. registerMenuCommand(); // 重新注册(不可用)脚本菜单
  102. }
  103. if (document.getElementById('XIU2DarkMode')) {
  104. document.getElementById('XIU2DarkMode').remove(); // 即时修改样式
  105. addStyle();
  106. }
  107. }
  108.  
  109.  
  110. // 切换暗黑模式
  111. function menu_toggle(menu_status, Name) {
  112. menu_status = parseInt(menu_status)
  113. if (menu_status >= 3){
  114. menu_status = 1;
  115. } else {
  116. menu_status += 1;
  117. }
  118. GM_setValue(`${Name}`, menu_status);
  119. location.reload(); // 刷新网页
  120. };
  121.  
  122.  
  123. // 菜单开关
  124. function menu_switch(menu_status, Name, Tips) {
  125. if (menu_status == 'true'){
  126. GM_setValue(`${Name}`, false);
  127. GM_notification({text: `已关闭 [${Tips}] 功能\n(刷新网页后生效)`, timeout: 3500});
  128. }else{
  129. GM_setValue(`${Name}`, true);
  130. GM_notification({text: `已开启 [${Tips}] 功能\n(刷新网页后生效)`, timeout: 3500});
  131. }
  132. registerMenuCommand(); // 重新注册(不可用)脚本菜单
  133. };
  134.  
  135.  
  136. // 返回菜单值
  137. function menu_value(menuName) {
  138. for (let menu of menu_ALL) {
  139. if (menu[0] == menuName) {
  140. return menu[3]
  141. }
  142. }
  143. }
  144.  
  145.  
  146. // 添加样式
  147. function addStyle() {
  148. let remove = false, style_Add = document.createElement('style'),
  149. hours = new Date().getHours(),
  150. style_10 = menu_value('menu_customMode1').split('|'),
  151. style_20 = menu_value('menu_customMode2').split('|'),
  152. style_30 = menu_value('menu_customMode3').split('|'),
  153. style = ``,
  154. style_00 = `html, body {background-color: #ffffff;}`,
  155. style_11 = `html {filter: brightness(${style_10[0]}%) !important;}`,
  156. style_11_firefox = `html {filter: brightness(${style_10[0]}%) !important; background-image: url();}`,
  157. style_12 = `html {filter: brightness(${style_10[1]}%) !important;}`,
  158. style_12_firefox = `html {filter: brightness(${style_10[1]}%) !important; background-image: url();}`,
  159. style_21 = `html {filter: brightness(${style_20[0]}%) sepia(${style_20[1]}%) !important;}`,
  160. style_21_firefox = `html {filter: brightness(${style_20[0]}%) sepia(${style_20[1]}%) !important; background-image: url();}`,
  161. style_22 = `html {filter: brightness(${style_20[2]}%) sepia(${style_20[3]}%) !important;}`,
  162. style_22_firefox = `html {filter: brightness(${style_20[2]}%) sepia(${style_20[3]}%) !important; background-image: url();}`,
  163. style_31 = `html {filter: invert(${style_30[0]}%) !important;} img, video {filter: invert(1) !important;}`,
  164. style_31_firefox = `html {filter: invert(${style_30[0]}%) !important; background-image: url();} img, video {filter: invert(1) !important;}`;
  165.  
  166. // Firefox 浏览器需要特殊对待
  167. if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) {
  168. style_11 = style_11_firefox
  169. style_12 = style_12_firefox
  170. style_21 = style_21_firefox
  171. style_22 = style_22_firefox
  172. style_31 = style_31_firefox
  173. }
  174.  
  175. // 白天(7点到19点)
  176. if (hours > 6 && hours < 19) {
  177. if (menu_value('menu_runDuringTheDay')) {
  178. style_12 = style_11
  179. style_22 = style_21
  180. } else {
  181. style_12 = style_22 = ''
  182. }
  183. }
  184.  
  185. switch(menu_value('menu_darkModeType')) {
  186. case 1:
  187. style += style_12;
  188. break;
  189. case 2:
  190. style += style_22;
  191. break;
  192. case 3:
  193. style += style_31;
  194. break;
  195. }
  196. style_Add.id = 'XIU2DarkMode';
  197. style_Add.type = 'text/css';
  198. //console.log(document,document.lastChild,document.querySelector('html'))
  199. if (document.lastChild) {
  200. document.lastChild.appendChild(style_Add).textContent = style;
  201. } else { // 发现个别网站速度太慢的话,就会出现脚本运行太早,连 html 标签都还没加载。。。
  202. let timer1 = setInterval(function(){ // 每 5 毫秒检查一下 html 是否已存在
  203. if (document.lastChild) {
  204. clearInterval(timer1); // 取消定时器
  205. document.lastChild.appendChild(style_Add).textContent = style;
  206. }
  207. }, 5);
  208. }
  209.  
  210. // 为了避免 body 还没加载导致无法检查是否设置背景颜色
  211. let timer = setInterval(function(){ // 每 10 毫秒检查一下 body 是否已存在
  212. if (document.body) {
  213. clearInterval(timer); // 取消定时器(每 10 毫秒一次的)
  214. setTimeout(function(){ // 为了避免太快 body 的 CSS 还没加载上,先延迟 150 毫秒(缺点就是可能会出现短暂一闪而过的暗黑滤镜)
  215. console.log('html:', window.getComputedStyle(document.lastChild).backgroundColor, 'body:', window.getComputedStyle(document.body).backgroundColor)
  216. if (window.getComputedStyle(document.body).backgroundColor === 'rgba(0, 0, 0, 0)' && window.getComputedStyle(document.lastChild).backgroundColor === 'rgba(0, 0, 0, 0)') {
  217. // 如果 body 没有 CSS 背景颜色,那就需要添加一个背景颜色,否则影响滤镜效果
  218. let style_Add2 = document.createElement('style');
  219. style_Add2.id = 'XIU2DarkMode2';
  220. document.lastChild.appendChild(style_Add2).textContent = style_00;
  221. } else if (window.getComputedStyle(document.body).backgroundColor === 'rgb(0, 0, 0)' || getColorValue(document.body) > 0 && getColorValue(document.body) < 898989 || getColorValue(document.lastChild) > 0 && getColorValue(document.lastChild) < 898989 || window.getComputedStyle(document.body).backgroundColor === 'rgba(0, 0, 0, 0)' && window.getComputedStyle(document.lastChild).backgroundColor === 'rgb(0, 0, 0)') {
  222. // 如果是黑色 (等于0,0,0) 或深色 (小于 89,89,89),就停用本脚本滤镜
  223. if (menu_value('menu_autoRecognition')) { // 排除自带暗黑模式的网页 (beta)
  224. for (let i=0;i<websiteList.length;i++){ // 这些网站强制启用护眼模式滤镜
  225. if (websiteList[i] === location.host) return
  226. }
  227. console.log('检测到当前网页自带暗黑模式,停用本脚本滤镜...')
  228. document.getElementById('XIU2DarkMode').remove();
  229. remove = true;
  230. }
  231. }
  232. }, 150);
  233.  
  234. // 用来解决一些 CSS 加载缓慢的网站,可能会出现没有正确排除的问题,在没有找到更好的办法之前,先这样凑活着用
  235. setTimeout(function(){
  236. console.log('html:', window.getComputedStyle(document.lastChild).backgroundColor, 'body:', window.getComputedStyle(document.body).backgroundColor)
  237. if (window.getComputedStyle(document.body).backgroundColor === 'rgb(0, 0, 0)' || getColorValue(document.body) > 0 && getColorValue(document.body) < 898989 || getColorValue(document.lastChild) > 0 && getColorValue(document.lastChild) < 898989 || window.getComputedStyle(document.body).backgroundColor === 'rgba(0, 0, 0, 0)' && window.getComputedStyle(document.lastChild).backgroundColor === 'rgb(0, 0, 0)') {
  238. // 如果是黑色 (等于0,0,0) 或深色 (小于 89,89,89),就停用本脚本滤镜
  239. if (menu_value('menu_autoRecognition')) { // 排除自带暗黑模式的网页 (beta)
  240. for (let i=0;i<websiteList.length;i++){ // 这些网站强制启用护眼模式滤镜
  241. if (websiteList[i] === location.host) return
  242. }
  243. if (remove) return
  244. console.log('检测到当前网页自带暗黑模式,停用本脚本滤镜...')
  245. if (document.getElementById('XIU2DarkMode')) document.getElementById('XIU2DarkMode').remove();
  246. if (document.getElementById('XIU2DarkMode2')) document.getElementById('XIU2DarkMode2').remove();
  247. }
  248. }
  249. }, 1500);
  250. }
  251. }, 10);
  252.  
  253. // 用来解决一些 CSS 加载缓慢的网站,可能会出现没有正确排除的问题,在没有找到更好的办法之前,先这样凑活着用
  254. /*setTimeout(function(){
  255. console.log('html:', window.getComputedStyle(document.lastChild).backgroundColor, 'body:', window.getComputedStyle(document.body).backgroundColor)
  256. if (window.getComputedStyle(document.body).backgroundColor === 'rgb(0, 0, 0)' || getColorValue(document.body) > 0 && getColorValue(document.body) < 898989 || getColorValue(document.lastChild) > 0 && getColorValue(document.lastChild) < 898989) {
  257. // 如果是黑色 (等于0,0,0) 或深色 (小于 89,89,89),就停用本脚本滤镜
  258. if (menu_value('menu_autoRecognition')) { // 排除自带暗黑模式的网页 (beta)
  259. for (let i=0;i<websiteList.length;i++){ // 这些网站强制启用护眼模式滤镜
  260. if (websiteList[i] === location.host) return
  261. }
  262. if (remove) return
  263. console.log('检测到当前网页自带暗黑模式,停用本脚本滤镜...')
  264. if (document.getElementById('XIU2DarkMode')) document.getElementById('XIU2DarkMode').remove();
  265. if (document.getElementById('XIU2DarkMode2')) document.getElementById('XIU2DarkMode2').remove();
  266. }
  267. }
  268. }, 3000);*/
  269.  
  270. // 解决远景论坛会清理掉前面插入的 CSS 样式的问题
  271. if (location.hostname === 'bbs.pcbeta.com') {
  272. let timer1 = setInterval(function(){
  273. if (!document.getElementById('XIU2DarkMode')) {
  274. document.lastChild.appendChild(style_Add).textContent = style;
  275. clearInterval(timer1);
  276. }
  277. }, 10);
  278. }
  279. }
  280.  
  281. // 获取背景颜色值
  282. function getColorValue(e) {
  283. let rgbValueArry = window.getComputedStyle(e).backgroundColor.replace(/rgba|rgb|\(|\)| /g, '').split (',')
  284. return parseInt(rgbValueArry[0] + rgbValueArry[1] + rgbValueArry[2])
  285. }
  286. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址