keyToShowClass | 快捷键启动自定义样式

Press a shortcut key to activate the specified host's custom styling. | 点击某个快捷键,来启动你指定的host的自定义的样式

  1. // ==UserScript==
  2. // @name keyToShowClass | 快捷键启动自定义样式
  3. // @namespace https://leizingyiu.net
  4. // @match http*://*/*
  5. // @grant none
  6. // @version 20250309
  7. // @author leizingyiu
  8. // @description Press a shortcut key to activate the specified host's custom styling. | 点击某个快捷键,来启动你指定的host的自定义的样式
  9. // @license GNU AGPLv3
  10.  
  11. // ==/UserScript==
  12.  
  13. prefix = "yiu_lib_show_info_";
  14. // 定义样式模板字典
  15. const dict = {
  16. "example":"⬇️",
  17. "liblib.art": {
  18. KeyC: `
  19. .${prefix}$/{code/} [class^=ImageCard_mask],
  20. .${prefix}$/{code/} [class^=ImageCard_imageCard] {
  21. opacity: 1 !important;
  22. background: #00000000 !important;
  23. color: #000 !important;
  24. }
  25.  
  26. .${prefix}$/{code/} [class^=ImageCard_nickName],
  27. .${prefix}$/{code/} [class^=ImageGenerateInfoPopover_generateBtn] {
  28. color: #fff !important;
  29. text-shadow: unset !important;
  30. mix-blend-mode: difference;
  31. }
  32.  
  33. .${prefix}$/{code/} [class^=ImageCard_drawBtn],
  34. .${prefix}$/{code/} .opacity-0 {
  35. opacity: 1 !important;
  36. }
  37.  
  38. [class^=ImageCard_mask],
  39. [class^=ImageCard_imageCard] {
  40. transition: opacity 0.2s ease, background 0.2s ease, color 0.2s ease !important;
  41. }
  42.  
  43. [class^=ImageCard_nickName],
  44. [class^=ImageGenerateInfoPopover_generateBtn] {
  45. transition: text-shadow 0.2s ease, color 0.2s ease !important;
  46. }
  47.  
  48. [class^=ImageCard_drawBtn], .opacity-0 {
  49. transition: opacity 0.2s ease;
  50. }
  51. `,
  52. },
  53. // 可以扩展其他主机和按键
  54. };
  55.  
  56. // 获取当前主机名
  57. const currentHost = window.location.host;
  58.  
  59. function hasSetting(host) {
  60. for (const [hostKey, styles] of Object.entries(dict)) {
  61. if (host.includes(hostKey)) {
  62. return true; // 如果当前主机包含字典中的主机名,则返回对应的样式模板
  63. }
  64. }
  65. return false; // 如果没有匹配的主机名,返回 null
  66. }
  67.  
  68. // 根据主机名获取对应的样式模板
  69. function getHostStyles(host) {
  70. for (const [hostKey, styles] of Object.entries(dict)) {
  71. if (host.includes(hostKey)) {
  72. return styles; // 如果当前主机包含字典中的主机名,则返回对应的样式模板
  73. }
  74. }
  75. return null; // 如果没有匹配的主机名,返回 null
  76. }
  77.  
  78. // 动态生成样式内容
  79. function generateStyleContent(template, code) {
  80. return template.replace(/\$\/\{code\/\}/g, code); // 替换所有 $/{code/} 占位符
  81. }
  82.  
  83. // 初始化样式
  84. function initializeStyles() {
  85. const hostStyles = getHostStyles(currentHost); // 获取当前主机的样式模板
  86.  
  87. if (!hostStyles) {
  88. console.error(`未找到与主机 ${currentHost} 匹配的样式模板`);
  89. return;
  90. }
  91.  
  92. // 遍历主机的所有按键样式模板
  93. for (const [key, styleTemplate] of Object.entries(hostStyles)) {
  94. const styleContent = generateStyleContent(styleTemplate, key); // 替换占位符
  95.  
  96. const styleElement = document.createElement("style");
  97. styleElement.textContent = styleContent; // 设置样式内容
  98. document.head.appendChild(styleElement); // 添加到 <head>
  99. }
  100. }
  101.  
  102. // 初始化事件监听器
  103. function initializeEventListeners() {
  104. const hostStyles = getHostStyles(currentHost); // 获取当前主机的样式模板
  105.  
  106. if (!hostStyles) {
  107. console.error(`未找到与主机 ${currentHost} 匹配的样式模板`);
  108. return;
  109. }
  110.  
  111. const toggleClass = (e) => {
  112. const key = e.code; // 获取按键代码
  113. console.log("key to show class : toggleClass : start");
  114.  
  115. const isKeySupported = hostStyles.hasOwnProperty(key); // 检查按键是否在样式模板中
  116.  
  117. if (isKeySupported) {
  118. console.log("key to show class : toggleClass : KeySupported");
  119.  
  120. if (e.type === "keydown") {
  121. document.body.classList.add(`${prefix}${key}`); // 添加动态类名
  122. } else if (e.type === "keyup") {
  123. document.body.classList.remove(`${prefix}${key}`); // 移除动态类名
  124. }
  125. }
  126. };
  127.  
  128. window.addEventListener("keydown", toggleClass);
  129. window.addEventListener("keyup", toggleClass);
  130. }
  131.  
  132. // 主函数:初始化样式和事件监听器
  133. function main() {
  134. console.log("key to show class : main : start");
  135.  
  136. initializeStyles(); // 初始化样式
  137. initializeEventListeners(); // 初始化事件监听器
  138.  
  139. console.log("key to show class : main : end ");
  140. }
  141.  
  142. // window.addEventListener('load',function(){
  143. // if(hasSetting(currentHost)==true){
  144. // main();
  145. // }
  146. // })
  147.  
  148. /**
  149. * 监听页面状态变化的函数
  150. * @param {Object} options - 配置对象,用于启用或禁用特定事件监听
  151. * @param {boolean} options.onUrlChange - 是否监听地址栏变化(hashchange 和 popstate)
  152. * @param {boolean} options.onPageNavigation - 是否监听页面前进或后退(popstate)
  153. * @param {boolean} options.onPageLoad - 是否监听页面加载完成(DOMContentLoaded 和 load)
  154. * @param {Function} [options.commonCallback] - 通用回调函数,适用于所有事件
  155. * @param {Object} callbacks - 回调函数对象(可选)
  156. * @param {Function} callbacks.onUrlChangeCallback - 地址栏变化时的回调
  157. * @param {Function} callbacks.onPageNavigationCallback - 页面前进或后退时的回调
  158. * @param {Function} callbacks.onPageLoadCallback - 页面加载完成时的回调
  159. */
  160. function listenPageStateChanges(options = {}, callbacks = {}) {
  161. const {
  162. onUrlChange = false,
  163. onPageNavigation = false,
  164. onPageLoad = false,
  165. commonCallback, // 通用回调函数
  166. } = options;
  167.  
  168. const {
  169. onUrlChangeCallback = commonCallback,
  170. onPageNavigationCallback = commonCallback,
  171. onPageLoadCallback = commonCallback,
  172. } = callbacks;
  173.  
  174. // 1. 地址栏变化(hashchange 和 popstate)
  175. if (onUrlChange && typeof onUrlChangeCallback === "function") {
  176. window.addEventListener("hashchange", () => {
  177. onUrlChangeCallback(window.location.href);
  178. });
  179.  
  180. window.addEventListener("popstate", () => {
  181. onUrlChangeCallback(window.location.href);
  182. });
  183. }
  184.  
  185. // 2. 页面前进或后退(popstate)
  186. if (onPageNavigation && typeof onPageNavigationCallback === "function") {
  187. window.addEventListener("popstate", () => {
  188. onPageNavigationCallback(window.location.href);
  189. });
  190. }
  191.  
  192. // 3. 页面加载完成(DOMContentLoaded 和 load)
  193. if (onPageLoad && typeof onPageLoadCallback === "function") {
  194. document.addEventListener("DOMContentLoaded", () => {
  195. onPageLoadCallback("DOMContentLoaded");
  196. });
  197.  
  198. window.addEventListener("load", () => {
  199. onPageLoadCallback("load");
  200. });
  201. }
  202. }
  203.  
  204. console.log("key to show class", hasSetting(currentHost));
  205.  
  206. if (hasSetting(currentHost) == true) {
  207. listenPageStateChanges(
  208. {
  209. onUrlChange: true, // 启用地址栏变化监听
  210. onPageNavigation: true, // 启用页面导航监听
  211. onPageLoad: true, // 启用页面加载完成监听
  212. commonCallback: (data) => {
  213. main(data);
  214. },
  215. },
  216. {
  217. // 如果需要单独定义某个事件的回调,可以在这里覆盖 commonCallback
  218. // 例如:
  219. // onUrlChangeCallback: (newUrl) => {
  220. // console.log('单独处理地址栏变化:', newUrl);
  221. // },
  222. },
  223. );
  224. }

QingJ © 2025

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