网页限制解除器

深度解除网页复制内容限制 智能恢复右键菜单/文本选择/剪贴板操作/拖拽功能

目前为 2025-04-06 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name 网页限制解除器
  3. // @description 深度解除网页复制内容限制 智能恢复右键菜单/文本选择/剪贴板操作/拖拽功能
  4. // @version 1.0.1
  5. // @author 念柚
  6. // @namespace https://github.com/MiPoNianYou/UserScripts
  7. // @license GPL-3.0
  8. // @match *://*/*
  9. // @grant none
  10. // @run-at document-start
  11. // ==/UserScript==
  12.  
  13. class CopyRestrictionRemover {
  14. constructor() {
  15. this.InitializeObserver();
  16. this.ExecuteCoreFeatures();
  17. }
  18.  
  19. ExecuteCoreFeatures() {
  20. this.RemoveEventListeners(document);
  21. this.RemoveEventListeners(document.body);
  22. this.InjectLiberationStyles();
  23. this.BindGlobalEventHandlers();
  24. this.ProcessExistingElements();
  25. }
  26.  
  27. BindGlobalEventHandlers() {
  28. const EventConfigurations = [
  29. ['contextmenu', this.HandleContextMenu],
  30. ['selectstart', this.HandleSelection],
  31. ['copy', this.HandleClipboard],
  32. ['cut', this.HandleClipboard],
  33. ['paste', this.HandleClipboard]
  34. ];
  35.  
  36. EventConfigurations.forEach(([eventType, handler]) => {
  37. document.addEventListener(eventType, handler.bind(this), true);
  38. });
  39. }
  40.  
  41. HandleContextMenu(event) {
  42. event.stopPropagation();
  43. return true;
  44. }
  45.  
  46. HandleSelection(event) {
  47. event.stopPropagation();
  48. return true;
  49. }
  50.  
  51. HandleClipboard(event) {
  52. event.stopPropagation();
  53. return true;
  54. }
  55.  
  56. InjectLiberationStyles() {
  57. const StyleDeclaration = `
  58. * {
  59. -webkit-user-select: text !important;
  60. -moz-user-select: text !important;
  61. -ms-user-select: text !important;
  62. user-select: text !important;
  63. -webkit-user-drag: auto !important;
  64. -moz-user-drag: auto !important;
  65. user-drag: auto !important;
  66. }
  67. `;
  68.  
  69. const StyleElement = document.createElement('style');
  70. StyleElement.textContent = StyleDeclaration;
  71. document.head.appendChild(StyleElement);
  72. }
  73.  
  74. ProcessExistingElements() {
  75. document.querySelectorAll('*').forEach(element => {
  76. this.RemoveEventListeners(element);
  77. });
  78. }
  79.  
  80. RemoveEventListeners(element) {
  81. if (!element) return;
  82.  
  83. const RestrictedProperties = [
  84. 'oncontextmenu', 'onselectstart',
  85. 'oncopy', 'oncut', 'onpaste',
  86. 'ondrag', 'ondragstart'
  87. ];
  88.  
  89. RestrictedProperties.forEach(property => {
  90. element[property] = null;
  91. });
  92. }
  93.  
  94. InitializedMutationHandler(mutationsList) {
  95. for (const mutation of mutationsList) {
  96. if (mutation.type === 'childList') {
  97. mutation.addedNodes.forEach(node => {
  98. if (node.nodeType === Node.ELEMENT_NODE) {
  99. this.RemoveEventListeners(node);
  100. node.querySelectorAll('*').forEach(child => {
  101. this.RemoveEventListeners(child);
  102. });
  103. }
  104. });
  105. }
  106. }
  107. }
  108.  
  109. InitializeObserver() {
  110. this.DomObserver = new MutationObserver(this.InitializedMutationHandler.bind(this));
  111. this.DomObserver.observe(document.documentElement, {
  112. childList: true,
  113. subtree: true,
  114. attributes: false,
  115. characterData: false
  116. });
  117. }
  118. }
  119.  
  120. new CopyRestrictionRemover();