护眼模式

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

目前为 2021-05-13 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name 护眼模式
  3. // @version 1.0.1
  4. // @author X.I.U
  5. // @description 最简单的全网通用护眼模式、夜间模式、暗黑模式
  6. // @match *://*/*
  7. // @icon https://i.loli.net/2021/03/07/rdijeYm83pznxWq.png
  8. // @grant GM_registerMenuCommand
  9. // @grant GM_unregisterMenuCommand
  10. // @grant GM_getValue
  11. // @grant GM_setValue
  12. // @noframes
  13. // @license GPL-3.0 License
  14. // @run-at document-start
  15. // @namespace https://github.com/XIU2/UserScript
  16. // ==/UserScript==
  17.  
  18. (function() {
  19. var menu_ALL = [
  20. ['menu_runDuringTheDay', '白天保持开启 (比晚上更亮一点)', '白天保持开启', true],
  21. ['menu_darkModeType', '点击切换模式', '点击切换模式', 1]
  22. ], menu_ID = [];
  23. for (let i=0;i<menu_ALL.length;i++){ // 如果读取到的值为 null 就写入默认值
  24. if (GM_getValue(menu_ALL[i][0]) == null){GM_setValue(menu_ALL[i][0], menu_ALL[i][3])};
  25. }
  26. registerMenuCommand();
  27. addStyle();
  28.  
  29.  
  30. // 注册脚本菜单
  31. function registerMenuCommand() {
  32. if (menu_ID.length > menu_ALL.length){ // 如果菜单ID数组多于菜单数组,说明不是首次添加菜单,需要卸载所有脚本菜单
  33. for (let i=0;i<menu_ID.length;i++){
  34. GM_unregisterMenuCommand(menu_ID[i]);
  35. }
  36. }
  37. for (let i=0;i<menu_ALL.length;i++){ // 循环注册脚本菜单
  38. menu_ALL[i][3] = GM_getValue(menu_ALL[i][0]);
  39. if (menu_ALL[i][0] === 'menu_darkModeType') {
  40. if (menu_ALL[i][3] > 3){ // 避免在减少 raw 数组后,用户储存的数据大于数组而报错
  41. menu_ALL[i][3] = 1;
  42. GM_setValue('menu_darkModeType', menu_ALL[i][3]);
  43. }
  44. menu_ID[i] = GM_registerMenuCommand(`🔄 [ ${menu_ALL[i][3]} ] ${menu_ALL[i][1]}`, function(){menu_toggle(`${menu_ALL[i][3]}`,`${menu_ALL[i][0]}`)});
  45. } else {
  46. 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]}`)});
  47. }
  48. }
  49. 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://greasyfork.org/zh-CN/scripts/412212/feedback', {active: true,insert: true,setParent: true});});
  50. }
  51.  
  52.  
  53. // 切换暗黑模式
  54. function menu_toggle(menu_status, Name) {
  55. menu_status = parseInt(menu_status)
  56. if (menu_status >= 3){
  57. menu_status = 1;
  58. } else {
  59. menu_status += 1;
  60. }
  61. GM_setValue(`${Name}`, menu_status);
  62. location.reload(); // 刷新网页
  63. };
  64.  
  65.  
  66. // 菜单开关
  67. function menu_switch(menu_status, Name, Tips) {
  68. if (menu_status == 'true'){
  69. GM_setValue(`${Name}`, false);
  70. GM_notification({text: `已关闭 [${Tips}] 功能\n(刷新网页后生效)`, timeout: 3500});
  71. }else{
  72. GM_setValue(`${Name}`, true);
  73. GM_notification({text: `已开启 [${Tips}] 功能\n(刷新网页后生效)`, timeout: 3500});
  74. }
  75. registerMenuCommand(); // 重新注册脚本菜单
  76. };
  77.  
  78.  
  79. // 返回菜单值
  80. function menu_value(menuName) {
  81. for (let menu of menu_ALL) {
  82. if (menu[0] == menuName) {
  83. return menu[3]
  84. }
  85. }
  86. }
  87.  
  88.  
  89. // 添加样式
  90. function addStyle() {
  91. let grayLevel,rgbValueArry,
  92. style_Add = document.createElement('style'),
  93. hours = new Date().getHours(),
  94. style = ``,
  95. style_00 = `body {background-color: #ffffff !important;}`,
  96. style_11 = `html {filter: brightness(80%) !important;}`,
  97. style_11_firefox = `html {filter: brightness(80%) !important; background-image: url();}`,
  98. style_12 = `html {filter: brightness(70%) !important;}`,
  99. style_12_firefox = `html {filter: brightness(70%) !important; background-image: url();}`,
  100. style_21 = `html {filter: brightness(80%) sepia(20%) !important;}`,
  101. style_21_firefox = `html {filter: brightness(80%) sepia(20%) !important; background-image: url();}`,
  102. style_22 = `html {filter: brightness(70%) sepia(30%) !important;}`,
  103. style_22_firefox = `html {filter: brightness(70%) sepia(30%) !important; background-image: url();}`,
  104. style_31 = `html {filter: invert(80%) !important;} img, video {filter: invert(1) !important;}`,
  105. style_31_firefox = `html {filter: invert(80%) !important;} img, video {filter: invert(1) !important; background-image: url();}`;
  106.  
  107. // 判断网页是否没有设置背景颜色(没有背景颜色会导致滤镜对背景颜色无效)
  108. if (document.body) {
  109. rgbValueArry = window.getComputedStyle(document.body).backgroundColor.replace ('rgb(', '').replace ('rgba(', '').replace (')', '').split (', ');
  110. grayLevel = rgbValueArry [0] + rgbValueArry [1] + rgbValueArry [2];
  111. if (grayLevel === "000") style += style_00
  112. }
  113.  
  114. // Firefox 浏览器需要特殊对待
  115. if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) {
  116. style_11 = style_11_firefox
  117. style_12 = style_12_firefox
  118. style_21 = style_21_firefox
  119. style_22 = style_22_firefox
  120. style_31 = style_31_firefox
  121. }
  122.  
  123. // 白天(7点到19点)
  124. if (hours > 6 && hours < 19) {
  125. if (menu_value('menu_runDuringTheDay')) {
  126. style_12 = style_11
  127. style_22 = style_21
  128. } else {
  129. style_12 = style_22 = ''
  130. }
  131. }
  132.  
  133. switch(menu_value('menu_darkModeType')) {
  134. case 1:
  135. style += style_12;
  136. break;
  137. case 2:
  138. style += style_22;
  139. break;
  140. case 3:
  141. style += style_31;
  142. break;
  143. }
  144. style_Add.innerHTML = style;
  145. if (document.head) {
  146. document.head.appendChild(style_Add);
  147. } else { // 为了避免脚本运行的时候 head 还没加载导致报错
  148. let timer = setInterval(function(){
  149. if (document.head) {
  150. document.head.appendChild(style_Add);
  151. clearInterval(timer);
  152. }
  153. }, 1);
  154. }
  155.  
  156. // 为了避免 body 还没加载导致无法检查是否设置背景颜色的备用措施
  157. if (!grayLevel) {
  158. let timer2 = setInterval(function(){
  159. if (document.body) {
  160. let rgbValueArry = window.getComputedStyle(document.body).backgroundColor.replace ('rgb(', '').replace ('rgba(', '').replace (')', '').split (', '),
  161. style_Add1 = document.createElement('style');
  162. if (rgbValueArry [0] + rgbValueArry [1] + rgbValueArry [2] === "000") {
  163. style_Add1.innerHTML = 'body {background-color: #ffffff !important;}';
  164. document.head.appendChild(style_Add1);
  165. }
  166. clearInterval(timer2);
  167. }
  168. }, 1);
  169. }
  170. }
  171. })();