Dark Mode Toggle

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

目前为 2025-03-16 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Dark Mode Toggle
  3. // @namespace https://github.com/Alistair1231/my-userscripts/
  4. // @version 0.2.1
  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://greasyfork.org/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. }
  34. img, video, iframe, object, embed, canvas, svg {
  35. -webkit-filter: invert(${CONFIG.mediaInversionPercent}%);
  36. filter: invert(${CONFIG.mediaInversionPercent}%);
  37. }
  38. `;
  39.  
  40. // Run initial setup immediately
  41. init();
  42.  
  43. // Wait for DOM to be ready before creating the button
  44. document.addEventListener("DOMContentLoaded", () => {
  45. createButton();
  46. });
  47.  
  48. // !
  49. // ! Functions
  50. // !
  51. // Function to create the toggle button
  52. function createButton() {
  53. if (!btn) {
  54. btn = document.createElement("button");
  55. btn.textContent = "🌓 Toggle Dark Mode";
  56. btn.style.cssText = `
  57. position: fixed;
  58. bottom: 20px;
  59. right: 20px;
  60. z-index: 2147483647 !important;
  61. padding: 8px 12px;
  62. cursor: pointer;
  63. border-radius: 4px;
  64. background: #fff;
  65. color: #333;
  66. box-shadow: 0 2px 5px rgba(0,0,0,0.2);
  67. opacity: 0;
  68. visibility: hidden;
  69. transition: opacity 0.3s ease;
  70. `;
  71. btn.addEventListener("click", () => {
  72. if (window.localStorage.darkMode === "true") {
  73. window.localStorage.darkMode = false;
  74. } else if (window.localStorage.darkMode === "false") {
  75. window.localStorage.darkMode = true;
  76. } else {
  77. window.localStorage.darkMode = true;
  78. }
  79. window.location.reload();
  80. });
  81. document.body.appendChild(btn);
  82. }
  83. }
  84.  
  85. function handleEscPress() {
  86. const now = Date.now();
  87. if (now - lastEscPress < CONFIG.doublePressDelay) {
  88. showToggleUI();
  89. }
  90. lastEscPress = now;
  91. }
  92.  
  93. function showToggleUI() {
  94. clearTimeout(uiTimeout);
  95. if (btn) {
  96. btn.style.visibility = "visible";
  97. btn.style.opacity = "1";
  98. }
  99. uiTimeout = setTimeout(() => {
  100. if (btn) {
  101. btn.style.opacity = "0";
  102. setTimeout(() => {
  103. btn.style.visibility = "hidden";
  104. }, 300);
  105. }
  106. }, CONFIG.uiTimeout);
  107. }
  108.  
  109. // Initial setup that can run immediately
  110. function init() {
  111. // Add keydown listener for Escape and Alt+Shift+D
  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. })();