「水水」链接跳转

自动跳过各种链接跳转页面,支持知乎,贴吧,QQ 和 QQ 邮箱等;

安装此脚本?
作者推荐脚本

您可能也喜欢「水水」复制标题网址

安装此脚本
  1. // ==UserScript==
  2. // @name 「水水」链接跳转
  3. // @namespace https://www.wdssmq.com/
  4. // @version 1.0.0
  5. // @author 沉冰浮水
  6. // @description 自动跳过各种链接跳转页面,支持知乎,贴吧,QQ 和 QQ 邮箱等;
  7. // @license MIT
  8. // @null ----------------------------
  9. // @contributionURL https://github.com/wdssmq#%E4%BA%8C%E7%BB%B4%E7%A0%81
  10. // @contributionAmount 5.93
  11. // @null ----------------------------
  12. // @link https://github.com/wdssmq/userscript
  13. // @link https://afdian.com/@wdssmq
  14. // @link https://gf.qytechs.cn/zh-CN/users/6865-wdssmq
  15. // @null ----------------------------
  16. // @noframes
  17. // @run-at document-end
  18. // @match https://jump.bdimg.com/f*
  19. // @match https://jump2.bdimg.com/f*
  20. // @match http://jump.bdimg.com/safecheck/index?url=*
  21. // @match http://jump2.bdimg.com/safecheck/index?url=*
  22. // @match https://tieba.baidu.com/safecheck/index?url=*
  23. // @match https://c.pc.qq.com/middlem.html?pfurl=*
  24. // @match https://mail.qq.com/cgi-bin/readtemplate?t=*
  25. // @match https://www.jianshu.com/go-wild*
  26. // @match https://www.v2ex.com/t/*
  27. // @match https://link.zhihu.com/*
  28. // @match https://link.juejin.cn/?target=*
  29. // @grant GM_registerMenuCommand
  30. // @grant GM_setValue
  31. // @grant GM_getValue
  32. // ==/UserScript==
  33.  
  34. /* eslint-disable */
  35. /* jshint esversion: 6 */
  36.  
  37. (function () {
  38. 'use strict';
  39.  
  40. const gm_name = "UrlGo";
  41.  
  42. // 初始常量或函数
  43. const curUrl = window.location.href;
  44. const curHost = window.location.host;
  45.  
  46. // -------------------------------------
  47.  
  48. const _log = (...args) => console.log(`[${gm_name}]\n`, ...args);
  49.  
  50. // -------------------------------------
  51.  
  52. // const $ = window.$ || unsafeWindow.$;
  53. function $n(e) {
  54. return document.querySelector(e);
  55. }
  56. function $na(e) {
  57. return document.querySelectorAll(e);
  58. }
  59.  
  60. // 指定元素内查找子元素
  61. function fnFindDom(el, selector) {
  62. return el.querySelectorAll(selector);
  63. }
  64.  
  65. const _config = {
  66. data: {},
  67. dataDef: {
  68. 倒计时: 5,
  69. },
  70. menuCommand: () => {
  71. const _this = _config;
  72. for (const key in _this.data) {
  73. if (Object.hasOwnProperty.call(_this.data, key)) {
  74. GM_registerMenuCommand(`${key}:${_this.data[key]}`, () => {
  75. const newValue = prompt(`请输入新的${key}值`, _this.data[key]);
  76. if (newValue !== null) {
  77. _this.data[key] = newValue;
  78. GM_setValue("config", _this.data);
  79. _log(`已将${key}值修改为:${newValue}`);
  80. }
  81. });
  82. }
  83. }
  84. },
  85. load: () => {
  86. const _this = _config;
  87. _config.data = GM_getValue("config", _this.dataDef);
  88. _config.menuCommand();
  89. },
  90. };
  91.  
  92. _config.load();
  93.  
  94. // 从页面中获取链接
  95. function fnGetUrlInDOM(selector, attrName) {
  96. const $dom = $n(selector);
  97. if ($dom) {
  98. return $dom[attrName];
  99. }
  100. return null;
  101. }
  102.  
  103. // 获取链接中的参数
  104. function fnGetParamInUrl(name, url) {
  105. const match = RegExp("[?&]" + name + "=(?<value>[^&]*)").exec(url);
  106. return match && decodeURIComponent(match.groups.value);
  107. }
  108.  
  109. // 监测网址是否带有协议
  110. function fnCheckUrl(url) {
  111. if (url.indexOf("http") === 0) {
  112. return url;
  113. }
  114. return "http://" + url;
  115. }
  116.  
  117. const siteList = [
  118. {
  119. name: "百度贴吧",
  120. hostList: ["jump2.bdimg.com", "tieba.baidu.com"],
  121. url: fnGetUrlInDOM("p.link", "textContent"),
  122. tipNode: [$n("p.content"), "after"],
  123. },
  124. {
  125. name: "QQ 客户端",
  126. hostList: ["c.pc.qq.com"],
  127. url: fnGetUrlInDOM("#url", "textContent"),
  128. tipNode: [$n("p.ui-title"), "after"],
  129. },
  130. {
  131. name: "QQ 邮箱",
  132. hostList: ["mail.qq.com"],
  133. url: fnGetUrlInDOM(".safety-url", "textContent"),
  134. tipNode: [$n(".safety-url"), "after"],
  135. },
  136. {
  137. name: "简书",
  138. hostList: ["www.jianshu.com"],
  139. url: fnGetParamInUrl("url", curUrl),
  140. },
  141. {
  142. name: "知乎",
  143. hostList: ["link.zhihu.com"],
  144. url: fnGetUrlInDOM("p.link", "textContent"),
  145. },
  146. {
  147. name: "掘金",
  148. hostList: ["link.juejin.cn"],
  149. url: fnGetParamInUrl("target", curUrl),
  150. tipNode: [$n("p.title"), "after"],
  151. },
  152. ];
  153.  
  154. // 显示提示
  155. function fnShowTip(tipNode, text, url) {
  156. console.log(text);
  157. const $node = tipNode[0];
  158. const $insertTips = `<p class="go-tips" style="color: red;text-align: center;">
  159. <span>${text}</span>
  160. <a href="${url}" title="点击跳转">点击跳转</a>
  161. </p>`;
  162. const $tips = $n(".go-tips");
  163. // 判断是否已经有提示
  164. if ($tips) {
  165. $tips.querySelector("span").textContent = text;
  166. return;
  167. }
  168. switch (tipNode[1]) {
  169. default:
  170. case "after":
  171. $node.insertAdjacentHTML("afterend", $insertTips);
  172. break;
  173. }
  174. }
  175.  
  176. // 各种中转页跳过
  177. siteList.forEach((site) => {
  178. const { name, hostList, url } = site;
  179. if (hostList.includes(curHost)) {
  180. if (!url) {
  181. return;
  182. }
  183. const newUrl = fnCheckUrl(url);
  184. if (site.tipNode) {
  185. let cntDown = _config.data["倒计时"];
  186. setInterval(() => {
  187. if (cntDown <= 0) {
  188. window.location.href = newUrl;
  189. return;
  190. }
  191. fnShowTip(site.tipNode, `即将跳转到,剩余 ${cntDown} 秒`, newUrl);
  192. cntDown--;
  193. }, 1000);
  194. } else {
  195. setTimeout(() => {
  196. window.location.href = newUrl;
  197. }, 10000);
  198. }
  199. }
  200. });
  201.  
  202. // 百度贴吧的各种链接统一
  203. const arrHostList = [
  204. "jump.bdimg.com",
  205. "jump2.bdimg.com",
  206. ];
  207.  
  208. if (arrHostList.includes(curHost)) {
  209. const newUrl = window.location.href.replace(curHost, "tieba.baidu.com");
  210. window.location.href = newUrl;
  211. }
  212.  
  213. // 指定元素中的链接增加 target="_blank"
  214. const config = [
  215. [".markdown_body", ".reply_content"],
  216. ];
  217.  
  218. const fnSetBlank = ($a) => {
  219. $a.setAttribute("target", "_blank");
  220. };
  221.  
  222. config.forEach((e) => {
  223. const selector = e.join(",");
  224. const $$container = $na(selector);
  225. // // print $$container
  226. // _log($$container);
  227. // 遍历 $$container
  228. [].forEach.call($$container, ($el) => {
  229. const $$a = fnFindDom($el, "a");
  230. // _log($$a);
  231. if ($$a.length > 0) {
  232. [].map.call($$a, fnSetBlank);
  233. }
  234. });
  235. });
  236.  
  237. })();

QingJ © 2025

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