Dark Mode Toggle

dark mode using inversion, double-hit Esc for toggle button

  1. // ==UserScript==
  2. // @name Dark Mode Toggle
  3. // @namespace https://github.com/Alistair1231/my-userscripts/
  4. // @version 0.3.0
  5. // @description dark mode using inversion, double-hit Esc for toggle button
  6. // @author Alistair1231
  7. // @license GPL-3.0
  8. // @match *://*/*
  9. // @run-at document-start
  10. // @grant GM.addStyle
  11. // ==/UserScript==
  12. // https://github.com/Alistair1231/my-userscripts/blob/master/dark-mode-toggle.user.js
  13. // https://gf.qytechs.cn/en/scripts/530023-dark-mode-toggle
  14.  
  15. (function () {
  16. "use strict";
  17.  
  18. const CONFIG = {
  19. inversionPercent: 90,
  20. mediaInversionPercent: 100,
  21. uiTimeout: 3000,
  22. doublePressDelay: 500,
  23. };
  24.  
  25. let isActive = false;
  26. let lastEscPress = 0;
  27. let uiTimeout;
  28. let btn = null;
  29. const style = `
  30. html {
  31. -webkit-filter: invert(${CONFIG.inversionPercent}%);
  32. filter: invert(${CONFIG.inversionPercent}%);
  33. background-color: white;
  34. }
  35. img, video, iframe, object, embed, canvas, svg {
  36. -webkit-filter: invert(${CONFIG.mediaInversionPercent}%);
  37. filter: invert(${CONFIG.mediaInversionPercent}%);
  38. }
  39. `;
  40.  
  41. // Run initial setup immediately
  42. init();
  43.  
  44. // Wait for DOM to be ready before creating the button
  45. document.addEventListener("DOMContentLoaded", () => {
  46. createButton();
  47. });
  48.  
  49. // !
  50. // ! Functions
  51. // !
  52. // Function to create the toggle button
  53. function createButton() {
  54. if (!btn) {
  55. btn = document.createElement("button");
  56. btn.textContent = "🌓 Toggle Dark Mode";
  57. btn.style.cssText = `
  58. position: fixed;
  59. bottom: 20px;
  60. right: 20px;
  61. z-index: 2147483647 !important;
  62. padding: 8px 12px;
  63. cursor: pointer;
  64. border-radius: 4px;
  65. background: #fff;
  66. color: #333;
  67. box-shadow: 0 2px 5px rgba(0,0,0,0.2);
  68. opacity: 0;
  69. visibility: hidden;
  70. transition: opacity 0.3s ease;
  71. `;
  72. btn.addEventListener("click", () => {
  73. if (window.localStorage.darkMode === "true") {
  74. window.localStorage.darkMode = false;
  75. } else if (window.localStorage.darkMode === "false") {
  76. window.localStorage.darkMode = true;
  77. } else {
  78. window.localStorage.darkMode = true;
  79. }
  80. window.location.reload();
  81. });
  82. document.body.appendChild(btn);
  83. }
  84. }
  85.  
  86. function handleEscPress() {
  87. const now = Date.now();
  88. if (now - lastEscPress < CONFIG.doublePressDelay) {
  89. showToggleUI();
  90. }
  91. lastEscPress = now;
  92. }
  93.  
  94. function showToggleUI() {
  95. clearTimeout(uiTimeout);
  96. if (btn) {
  97. btn.style.visibility = "visible";
  98. btn.style.opacity = "1";
  99. }
  100. uiTimeout = setTimeout(() => {
  101. if (btn) {
  102. btn.style.opacity = "0";
  103. setTimeout(() => {
  104. btn.style.visibility = "hidden";
  105. }, 300);
  106. }
  107. }, CONFIG.uiTimeout);
  108. }
  109.  
  110. // Initial setup that can run immediately
  111. function init() {
  112. document.addEventListener("keydown", (e) => {
  113. if (e.key === "Escape") handleEscPress();
  114. });
  115.  
  116. // Check localStorage and apply dark mode if needed
  117. if (window.localStorage.darkMode === "true") {
  118. GM.addStyle(style);
  119. }
  120. }
  121. })();

QingJ © 2025

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