UserPanel

一个浮窗设置面板

当前为 2025-04-28 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/534265/1579409/UserPanel.js

  1. const createPanel = function () {
  2. // 创建宿主元素
  3. const container = document.createElement("div");
  4. container.id = "scriptSettings";
  5. // 创建 shadowRoot
  6. const shadowRoot = container.attachShadow({ mode: "open" });
  7.  
  8. // 插入样式和内容
  9. shadowRoot.innerHTML = `
  10. <style>
  11. * {
  12. margin: 0;
  13. padding: 0;
  14. box-sizing: border-box;
  15. }
  16.  
  17. .float-ball {
  18. position: fixed;
  19. right: 10px;
  20. top: 80%;
  21. transform: translateY(-50%);
  22. width: 40px;
  23. height: 40px;
  24. background: #4a90e2;
  25. border-radius: 50%;
  26. cursor: pointer;
  27. box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  28. transition: all 0.3s ease;
  29. display: flex;
  30. align-items: center;
  31. justify-content: center;
  32. z-index: 1000;
  33. }
  34.  
  35. .float-ball:hover {
  36. background: #357abd;
  37. transform: translateY(-50%) scale(1.1);
  38. }
  39.  
  40. .float-ball.active {
  41. transform: translateY(-50%) rotate(0deg);
  42. }
  43.  
  44. .menu-panel {
  45. position: absolute;
  46. right: 60px;
  47. top: 50%;
  48. transform: translateY(-50%) scale(0);
  49. transform-origin: right center;
  50. width: 200px;
  51. background: white;
  52. border-radius: 12px;
  53. padding: 16px;
  54. box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  55. opacity: 0;
  56. transition: all 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.28);
  57. }
  58.  
  59. .float-ball.active .menu-panel {
  60. transform: translateY(-50%) scale(1);
  61. opacity: 1;
  62. }
  63.  
  64. .menu-item {
  65. margin: 12px 0;
  66. display: flex;
  67. align-items: center;
  68. justify-content: space-between;
  69. }
  70.  
  71. .switch {
  72. width: 40px;
  73. height: 24px;
  74. background: #ddd;
  75. border-radius: 12px;
  76. position: relative;
  77. cursor: pointer;
  78. transition: all 0.3s ease;
  79. }
  80.  
  81. .switch.active {
  82. background: #4a90e2;
  83. }
  84.  
  85. .switch::after {
  86. content: "";
  87. position: absolute;
  88. width: 20px;
  89. height: 20px;
  90. background: white;
  91. border-radius: 50%;
  92. top: 2px;
  93. left: 2px;
  94. transition: all 0.3s ease;
  95. }
  96.  
  97. .switch.active::after {
  98. left: 18px;
  99. }
  100.  
  101. .input-field {
  102. width: 100%;
  103. padding: 6px 12px;
  104. border: 1px solid #ddd;
  105. border-radius: 6px;
  106. font-size: 14px;
  107. transition: all 0.3s ease;
  108. box-shadow: inset -1px -1px 1px 0px #357abd8c;
  109. cursor: pointer;
  110. caret-color: transparent; /* 隐藏光标 */
  111. }
  112.  
  113. .input-field:focus {
  114. outline: none;
  115. border-color: #4a90e2;
  116. box-shadow: 0 0 0 2px rgba(74, 144, 226, 0.2);
  117. }
  118.  
  119. .icon {
  120. width: 24px;
  121. height: 24px;
  122. fill: white;
  123. }
  124. </style>
  125.  
  126. <div class="float-ball">
  127. <svg class="icon" viewBox="0 0 24 24">
  128. <path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z" />
  129. </svg>
  130. <div class="menu-panel">
  131. <div class="menu-item">
  132. <span>点赞</span>
  133. <div class="switch like-switch"></div>
  134. </div>
  135. <div class="menu-item">
  136. <span>收藏</span>
  137. <div class="switch collect-switch"></div>
  138. </div>
  139. <input type="text" class="input-field" placeholder="粘贴接口地址" />
  140. </div>
  141. </div>
  142. `;
  143.  
  144. // 获取切换按钮(switch)
  145. const likeSwitch = shadowRoot.querySelector(".like-switch");
  146. const collectSwitch = shadowRoot.querySelector(".collect-switch");
  147.  
  148. // 初始化按钮状态(status)
  149. function initializeSwitches() {
  150. // 从 GM_getValue 获取状态并更新开关状态
  151. const likeStatus = GM_getValue("likeStatus", false); // 默认值为 false
  152. const collectStatus = GM_getValue("collectStatus", false); // 默认值为 false
  153.  
  154. // 设置初始状态
  155. if (likeStatus !== null) {
  156. likeSwitch.classList.toggle("active", likeStatus);
  157. }
  158.  
  159. if (collectStatus !== null) {
  160. collectSwitch.classList.toggle("active", collectStatus);
  161. }
  162. }
  163. // 绑定切换事件(event)
  164. likeSwitch.addEventListener("click", (event) => {
  165. // 阻止点击事件冒泡
  166. event.stopPropagation();
  167. const currentStatus = likeSwitch.classList.contains("active");
  168. const newStatus = !currentStatus;
  169. // 切换按钮状态
  170. likeSwitch.classList.toggle("active", newStatus);
  171. // 保存新的状态到 GM
  172. GM_setValue("likeStatus", newStatus);
  173. });
  174. collectSwitch.addEventListener("click", (event) => {
  175. // 阻止点击事件冒泡
  176. event.stopPropagation();
  177. const currentStatus = collectSwitch.classList.contains("active");
  178. const newStatus = !currentStatus;
  179. // 切换按钮状态
  180. collectSwitch.classList.toggle("active", newStatus);
  181. // 保存新的状态到 GM
  182. GM_setValue("collectStatus", newStatus);
  183. });
  184.  
  185. // 初始化页面加载时的状态
  186. initializeSwitches();
  187.  
  188. // 打开或关闭菜单(menu)
  189. const floatBall = shadowRoot.querySelector(".float-ball");
  190. // 点击页面其他地方时关闭菜单
  191. document.addEventListener("click", function () {
  192. floatBall.classList.remove("active");
  193. });
  194. // 点击浮窗显示或隐藏面板
  195. floatBall.addEventListener("click", function (event) {
  196. event.stopPropagation(); // 阻止冒泡
  197. floatBall.classList.toggle("active");
  198. });
  199.  
  200. // 获取 input 元素
  201. const inputField = shadowRoot.querySelector(".input-field");
  202. // 设置 URL 默认值(可以从 GM_getValue 获取已存储的 URL)
  203. const defaultURL = GM_getValue("storedURL", "");
  204. // 初始化 input 的值
  205. inputField.value = defaultURL;
  206. // 绑定点击事件,点击时粘贴剪贴板的 URL 到 input 中
  207. inputField.addEventListener("click", function () {
  208. // 使用 Clipboard API 来获取剪贴板内容
  209. navigator.clipboard
  210. .readText()
  211. .then((text) => {
  212. inputField.value = text; // 将剪贴板中的 URL 填充到 input 中
  213. GM_setValue("storedURL", text); // 存储该 URL
  214. })
  215. .catch((err) => {
  216. console.error("无法读取剪贴板内容:", err);
  217. });
  218. });
  219. return container;
  220. };

QingJ © 2025

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