Greasy Fork is available in English.

允许/禁止跳转到外部站点

默认允许从当前网页跳转到外部站点,点击按钮后开始拦截,7秒后自动隐藏(点击按钮后重置隐藏时间),页面刷新后重置。可用于阅读漫画、小说时拦截跳转到广告

  1. // ==UserScript==
  2. // @name 允许/禁止跳转到外部站点
  3. // @namespace https://greasyfork.org/zh-CN/users/1305708-ayours
  4. // @version 2.4
  5. // @description 默认允许从当前网页跳转到外部站点,点击按钮后开始拦截,7秒后自动隐藏(点击按钮后重置隐藏时间),页面刷新后重置。可用于阅读漫画、小说时拦截跳转到广告
  6. // @author AYour
  7. // @match *://*/*
  8. // @grant none
  9. // @run-at document-idle
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. let blockExternalLinks = false;
  17. let button;
  18. let hideButtonTimeout;
  19. let confirmTimeout;
  20.  
  21. function createButton() {
  22. if (button) {
  23. clearTimeout(hideButtonTimeout);
  24. button.remove();
  25. }
  26. button = document.createElement('button');
  27. button.id = 'block-external-links-btn';
  28. button.style.position = 'fixed';
  29. button.style.bottom = '50px';
  30. button.style.right = '20px';
  31. button.style.zIndex = '20000';
  32. button.textContent = '允许外部链接';
  33. document.body.appendChild(button);
  34.  
  35. button.addEventListener('click', toggleBlockExternalLinks);
  36.  
  37. hideButtonTimeout = setTimeout(hideButton, 7000);
  38. }
  39.  
  40. function toggleBlockExternalLinks() {
  41. blockExternalLinks = !blockExternalLinks;
  42. button.textContent = blockExternalLinks ? '禁止外部链接' : '允许外部链接';
  43. clearTimeout(hideButtonTimeout);
  44. hideButtonTimeout = setTimeout(hideButton, 7000);
  45. }
  46.  
  47. function hideButton() {
  48. button.style.display = 'none';
  49. }
  50.  
  51. function initialize() {
  52. createButton();
  53. document.addEventListener('click', checkExternalLinks);
  54. }
  55.  
  56. function checkExternalLinks(event) {
  57. var target = event.target;
  58. while (target != null) {
  59. if (target.tagName === 'A') {
  60. var url = new URL(target.href);
  61. var currentUrl = new URL(window.location.href);
  62. if (blockExternalLinks && url.origin !== currentUrl.origin) {
  63. event.preventDefault();
  64. // 自定义确认对话框
  65. customConfirm('您确定不跳转到外部链接吗?', function(result) {
  66. if (result) {
  67. clearTimeout(confirmTimeout);
  68. } else {
  69. blockExternalLinks = false;
  70. button.textContent = '允许外部链接';
  71. }
  72. });
  73. break;
  74. }
  75. }
  76. target = target.parentElement;
  77. }
  78. }
  79.  
  80. // 自定义确认对话框
  81. function customConfirm(message, callback) {
  82. // 创建一个自定义对话框
  83. const dialog = document.createElement('div');
  84. dialog.style.position = 'fixed';
  85. dialog.style.top = '50%';
  86. dialog.style.left = '50%';
  87. dialog.style.transform = 'translate(-50%, -50%)';
  88. dialog.style.backgroundColor = 'white';
  89. dialog.style.padding = '10px';
  90. dialog.style.border = '1px solid #ccc';
  91. dialog.textContent = message;
  92.  
  93. const confirmButton = document.createElement('button');
  94. confirmButton.textContent = '不跳转';
  95. confirmButton.addEventListener('click', function() {
  96. document.body.removeChild(dialog);
  97. callback(true);
  98. });
  99.  
  100. const cancelButton = document.createElement('button');
  101. cancelButton.textContent = '要跳转';
  102. cancelButton.addEventListener('click', function() {
  103. document.body.removeChild(dialog);
  104. callback(false);
  105. });
  106.  
  107. dialog.appendChild(confirmButton);
  108. dialog.appendChild(cancelButton);
  109. document.body.appendChild(dialog);
  110.  
  111. // 设置一个2秒的超时,如果用户不点击,则自动选择“不跳转”
  112. confirmTimeout = setTimeout(function() {
  113. document.body.removeChild(dialog);
  114. callback(true);
  115. }, 2000);
  116. }
  117.  
  118. window.addEventListener('beforeunload', function() {
  119. blockExternalLinks = false;
  120. if (button) {
  121. button.remove();
  122. }
  123. });
  124.  
  125. initialize();
  126. })();