Greasy Fork镜像脚本页面适用于网址增强

脚本详情页适用于网址不默认跳转搜索 转为可点击的文本链接并弹出提示

目前为 2024-06-08 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Greasy Fork镜像脚本页面适用于网址增强
  3. // @namespace https://gf.qytechs.cn/zh-CN/users/1169082-%E4%BA%BA%E6%B0%91%E7%9A%84%E5%8B%A4%E5%8A%A1%E5%91%98
  4. // @version 0.8
  5. // @description 脚本详情页适用于网址不默认跳转搜索 转为可点击的文本链接并弹出提示
  6. // @author 人民的勤务员 <millle@foxmail.com>
  7. // @match https://*.gf.qytechs.cn/zh-CN/scripts/*
  8. // @match https://*.sleazyfork.org/zh-CN/scripts/*
  9. // @icon https://www.google.com/s2/favicons?domain=https://gf.qytechs.cn
  10. // @license MIT
  11. // @grant GM_getValue
  12. // @grant GM_setValue
  13. // ==/UserScript==
  14.  
  15. (function() {
  16. 'use strict';
  17. let useWindowOpen = GM_getValue('useWindowOpen', false); // 默认在当前页面跳转
  18. let linkBehavior = GM_getValue('linkBehavior', 0);
  19.  
  20. function Toast(msg, duration) {
  21. duration = isNaN(duration) ? 3000 : duration;
  22. var m = document.createElement('div');
  23. m.innerHTML = msg;
  24. m.style.cssText = "max-width:60%;min-width: 150px;padding:0 14px;height: 40px;color: black;line-height: 40px;text-align: center;border-radius: 12px;position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);z-index: 2147483647;background: white;font-size: 16px;";
  25.  
  26.  
  27. document.body.appendChild(m);
  28. setTimeout(function () {
  29. var d = 0.5;
  30. m.style.transition = '-webkit-transform ' + d + 's ease-in, opacity ' + d + 's ease-in';
  31. m.style.opacity = '0'; setTimeout(function () { document.body.removeChild(m) }, d * 1000);
  32. }, duration);
  33. }
  34.  
  35. function navigateTo(url, useWindowOpen) {
  36. if (useWindowOpen) {
  37. window.open(url, '_blank');
  38. } else {
  39. window.location.href = url;
  40. }
  41. }
  42.  
  43. const ddElements = document.querySelectorAll('dd.script-show-applies-to ul.block-list.expandable > li');
  44.  
  45. ddElements.forEach(dd => {
  46. const link = dd.querySelector('a[title^="查看其他"]');
  47. const text = dd.textContent.trim();
  48. if (text.includes('*')) {
  49. return;
  50. }
  51. if (link) {
  52. link.addEventListener('click', function(event) {
  53. event.preventDefault();
  54. handleLinkClick(text);
  55. });
  56. } else {
  57. const newLink = document.createElement('a');
  58. newLink.textContent = text;
  59. newLink.href = '#';
  60. newLink.addEventListener('click', function(event) {
  61. event.preventDefault();
  62. handleLinkClick(text);
  63. });
  64. dd.textContent = '';
  65. dd.appendChild(newLink);
  66. }
  67. });
  68.  
  69. function handleLinkClick(linkText) {
  70. if (linkBehavior === 0) {
  71. // 创建自定义对话框
  72. const bodyBackgroundColor = window.getComputedStyle(document.body).backgroundColor;
  73.  
  74. const dialogBox = document.createElement('div');
  75. dialogBox.style.position = 'fixed';
  76. dialogBox.style.top = '50%';
  77. dialogBox.style.left = '50%';
  78. dialogBox.style.transform = 'translate(-50%, -50%)';
  79. dialogBox.style.background = bodyBackgroundColor;
  80. dialogBox.style.padding = '20px';
  81. dialogBox.style.boxShadow = '0 4px 6px rgba(0, 0, 0, 0.1)';
  82. dialogBox.style.borderRadius = '8px';
  83. dialogBox.style.zIndex = '9999';
  84. dialogBox.innerHTML = `
  85. <span id="closeBtn" style="position: absolute; top: 10px; right: 10px; color: red; cursor: pointer; font-size: 30px;">&times;</span>
  86. <p style="font-weight: bold; font-size: 20px;"> <span id="linkTextSpan" style="color: red;">${linkText}</span> 操作</p>
  87. <button id="forumSearchBtn">论坛搜索</button>
  88. <button id="openUrlBtn">打开网址</button>
  89. <button id="copyLinkBtn">复制链接</button>
  90. `;
  91. document.body.appendChild(dialogBox);
  92. // 记录对话框初始位置和鼠标初始位置
  93. // 记录对话框初始位置和鼠标/手指触摸初始位置
  94. let dialogInitialX, dialogInitialY, initialX, initialY;
  95.  
  96. // 鼠标按下/触摸开始事件
  97. dialogBox.addEventListener('mousedown', onMouseDown);
  98. dialogBox.addEventListener('touchstart', onTouchStart);
  99.  
  100. // 鼠标按下事件处理函数
  101. function onMouseDown(event) {
  102. dialogInitialX = dialogBox.offsetLeft;
  103. dialogInitialY = dialogBox.offsetTop;
  104. initialX = event.clientX;
  105. initialY = event.clientY;
  106.  
  107. // 鼠标移动事件
  108. document.addEventListener('mousemove', onMouseMove);
  109.  
  110. // 鼠标松开事件
  111. document.addEventListener('mouseup', onMouseUp);
  112. }
  113.  
  114. // 触摸开始事件处理函数
  115. function onTouchStart(event) {
  116. dialogInitialX = dialogBox.offsetLeft;
  117. dialogInitialY = dialogBox.offsetTop;
  118. initialX = event.touches[0].clientX;
  119. initialY = event.touches[0].clientY;
  120.  
  121. // 触摸移动事件
  122. document.addEventListener('touchmove', onTouchMove);
  123.  
  124. // 触摸结束事件
  125. document.addEventListener('touchend', onTouchEnd);
  126. }
  127.  
  128. // 鼠标移动事件处理函数
  129. function onMouseMove(event) {
  130. const deltaX = event.clientX - initialX;
  131. const deltaY = event.clientY - initialY;
  132.  
  133. // 更新对话框位置
  134. dialogBox.style.left = dialogInitialX + deltaX + 'px';
  135. dialogBox.style.top = dialogInitialY + deltaY + 'px';
  136. }
  137.  
  138. // 触摸移动事件处理函数
  139. function onTouchMove(event) {
  140. const deltaX = event.touches[0].clientX - initialX;
  141. const deltaY = event.touches[0].clientY - initialY;
  142.  
  143. // 更新对话框位置
  144. dialogBox.style.left = dialogInitialX + deltaX + 'px';
  145. dialogBox.style.top = dialogInitialY + deltaY + 'px';
  146. }
  147.  
  148. // 鼠标松开事件处理函数
  149. function onMouseUp() {
  150. // 移除鼠标移动事件监听器
  151. document.removeEventListener('mousemove', onMouseMove);
  152. document.removeEventListener('mouseup', onMouseUp);
  153. }
  154.  
  155. // 触摸结束事件处理函数
  156. function onTouchEnd() {
  157. // 移除触摸移动事件监听器
  158. document.removeEventListener('touchmove', onTouchMove);
  159. document.removeEventListener('touchend', onTouchEnd);
  160. }
  161. // 设置链接文本不可点击
  162. document.getElementById('linkTextSpan').style.pointerEvents = 'none';
  163. // 绑定关闭按钮点击事件
  164. document.getElementById('closeBtn').addEventListener('click', function() {
  165. document.body.removeChild(dialogBox);
  166. });
  167.  
  168. // 点击复制链接按钮复制文本到剪贴板
  169. document.getElementById('copyLinkBtn').addEventListener('click', function() {
  170. const linkText = document.getElementById('linkTextSpan').innerText;
  171.  
  172. // 创建一个临时的textarea元素来容纳文本
  173. const tempTextarea = document.createElement('textarea');
  174. tempTextarea.value = linkText;
  175. document.body.appendChild(tempTextarea);
  176.  
  177. // 选中文本并执行复制操作
  178. tempTextarea.select();
  179. document.execCommand('copy');
  180.  
  181. // 移除临时textarea元素
  182. document.body.removeChild(tempTextarea);
  183. document.body.removeChild(dialogBox);
  184. // 提示用户文本已复制到剪贴板
  185. Toast('文本已复制到剪贴板!', 1000);
  186. });
  187.  
  188. // 绑定论坛搜索按钮点击事件
  189. document.getElementById('forumSearchBtn').addEventListener('click', function() {
  190. const newUrl = `https://${location.host}/zh-CN/scripts/by-site/${linkText}`;
  191. navigateTo(newUrl, useWindowOpen);
  192. document.body.removeChild(dialogBox);
  193. });
  194.  
  195. // 绑定打开网址按钮点击事件
  196. document.getElementById('openUrlBtn').addEventListener('click', function() {
  197. const originalUrl = `https://${linkText}`;
  198. navigateTo(originalUrl, useWindowOpen);
  199. document.body.removeChild(dialogBox);
  200. });
  201. } else if (linkBehavior === 1) {
  202. const originalUrl = `https://${linkText}`;
  203. navigateTo(originalUrl, useWindowOpen);
  204. } else if (linkBehavior === 2) {
  205. const newUrl = `https://${location.host}/zh-CN/scripts/by-site/${linkText}`;
  206. navigateTo(newUrl, useWindowOpen);
  207. }
  208. }
  209.  
  210.  
  211.  
  212. const appliesToSection = document.querySelector('dt.script-show-applies-to');
  213. if (appliesToSection) {
  214. const changeConfigText = document.createElement('span');
  215. changeConfigText.textContent = '[适用于] ';
  216. changeConfigText.style.fontWeight= 'bold'; // Bold
  217.  
  218. // 创建复选框
  219. const checkboxLabel = document.createElement('label');
  220. checkboxLabel.textContent = '新窗口打开';
  221. checkboxLabel.style.marginLeft = '10px';
  222.  
  223. const checkboxInput = document.createElement('input');
  224. checkboxInput.type = 'checkbox';
  225. checkboxInput.checked = useWindowOpen;
  226. checkboxInput.style.marginRight = '5px';
  227.  
  228. checkboxInput.addEventListener('change', function() {
  229. useWindowOpen = checkboxInput.checked;
  230. GM_setValue('useWindowOpen', useWindowOpen);
  231. });
  232.  
  233. checkboxLabel.appendChild(checkboxInput);
  234.  
  235. // 添加选择框和复选框
  236. const selectList = document.createElement('select');
  237. selectList.style.width = '7em'; // 设置宽度为四个中文字符的宽度
  238. const options = [
  239. { value: 0, text: '弹出提示' },
  240. { value: 1, text: '打开网址' },
  241. { value: 2, text: '论坛搜索' }
  242. ];
  243. options.forEach(option => {
  244. const optionElement = document.createElement('option');
  245. optionElement.textContent = option.text;
  246. optionElement.value = option.value;
  247. if (linkBehavior === option.value) {
  248. optionElement.selected = true;
  249. }
  250. selectList.appendChild(optionElement);
  251. });
  252. selectList.addEventListener('change', function() {
  253. linkBehavior = parseInt(selectList.value);
  254. GM_setValue('linkBehavior', linkBehavior);
  255. Toast(`点击"适用于"网址已设置为: ${options.find(option => option.value === linkBehavior).text}`, 1000);
  256. });
  257.  
  258. appliesToSection.parentElement.appendChild(changeConfigText);
  259. appliesToSection.parentElement.appendChild(selectList);
  260. appliesToSection.parentElement.appendChild(checkboxLabel);
  261. }
  262. })();

QingJ © 2025

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