Disable blank target

在当前页面打开同域名超链接,而不是跳转新页面,适配所有网站,包括头条和网易。Disable open links in a new window/tab(based on the hostname).

目前為 2025-03-19 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Disable blank target
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.4
  5. // @description 在当前页面打开同域名超链接,而不是跳转新页面,适配所有网站,包括头条和网易。Disable open links in a new window/tab(based on the hostname).
  6. // @author Logan Wang
  7. // @copyright Logan Wang
  8. // @homepage https://github.com/azone
  9. // @license MIT
  10. // @match http*://*/*
  11. // @icon none
  12. // @grant none
  13. // @run-at document-start
  14. // ==/UserScript==
  15.  
  16. (function() {
  17. 'use strict';
  18.  
  19. const neteasyRe = /163\.com$/
  20. const toutiaoRe = /toutiao\.com$/
  21.  
  22. const originalURL = window.location;
  23.  
  24. if (toutiaoRe.test(originalURL.host)) {
  25. const listener = document.addEventListener;
  26. document.addEventListener = (event, listenerFunc, options) => {
  27. if (event !== 'click') {
  28. listener(event, listenerFunc, options);
  29. }
  30. };
  31. }
  32.  
  33. function shouldRemove(element) {
  34. const href = element.href;
  35. if (!href) {
  36. return false;
  37. }
  38.  
  39. const url = new URL(href);
  40. return !url.host || url.host === originalURL.host || neteasyRe.test(url.host);
  41. }
  42.  
  43. function removeBlankTargetIfNecessary(rootElement) {
  44. const selector = rootElement.querySelectorAll;
  45. if (!selector) {
  46. return;
  47. }
  48.  
  49. const elements = rootElement.querySelectorAll('a[target="_blank"]');
  50. for (const element of elements) {
  51. if (shouldRemove(element)) {
  52. element.removeAttribute('target');
  53. }
  54. }
  55. }
  56.  
  57. function removeBaseElements() {
  58. const baseElements = document.querySelectorAll('base[target="_blank"]');
  59. for (const base of baseElements) {
  60. base.parentNode.removeChild(base);
  61. }
  62. }
  63.  
  64. function processElements() {
  65. removeBlankTargetIfNecessary(document);
  66.  
  67. removeBaseElements();
  68. }
  69.  
  70. if (document.readyState === "loading") {
  71. document.addEventListener('DOMContentLoaded', (e) => {
  72. processElements();
  73. });
  74. } else {
  75. processElements();
  76. }
  77.  
  78. function observeChanges(records, observer) {
  79. for (const record of records) {
  80. if (record.type === 'attributes') {
  81. if (record.attributeName === 'target' && record.target.getAttribute(record.attributeName) === '_blank') {
  82. if (shouldRemove(record.target)) {
  83. record.target.removeAttribute(record.attributeName);
  84. } else if (record.target.nodeName === 'BASE') {
  85. record.target.parentNode.removeChild(record.target);
  86. }
  87. }
  88. } else if (record.addedNodes.length > 0) {
  89. for (const node of record.addedNodes) {
  90. if (node.nodeName === 'A' && shouldRemove(node)) {
  91. node.removeAttribute('target');
  92. } else if (node.nodeName === 'BASE' && node.getAttribute('target') === '_blank') {
  93. node.parentNode.removeChild(node);
  94. } else {
  95. removeBlankTargetIfNecessary(node);
  96. }
  97. }
  98. }
  99. }
  100. }
  101.  
  102. const observer = new MutationObserver(observeChanges);
  103. observer.observe(document, {attributes: true, subtree: true, childList: true});
  104. })();

QingJ © 2025

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