網頁限制解除

通殺大部分網站,可以解除禁止復制、剪切、選擇文本、右鍵菜單的限制。

  1. // ==UserScript==
  2. // @namespace https://www.github.com/Cat7373/
  3.  
  4. // @name 网页限制解除
  5. // @name:en Remove web limits
  6. // @name:zh 网页限制解除
  7. // @name:zh-CN 网页限制解除
  8. // @name:zh-TW 網頁限制解除
  9. // @name:ja ウェブの規制緩和
  10.  
  11. // @description 通杀大部分网站,可以解除禁止复制、剪切、选择文本、右键菜单的限制。
  12. // @description:en Pass to kill most of the site, you can lift the restrictions prohibited to copy, cut, select the text, right-click menu.
  13. // @description:zh 通杀大部分网站,可以解除禁止复制、剪切、选择文本、右键菜单的限制。
  14. // @description:zh-CN 通杀大部分网站,可以解除禁止复制、剪切、选择文本、右键菜单的限制。
  15. // @description:zh-TW 通殺大部分網站,可以解除禁止復制、剪切、選擇文本、右鍵菜單的限制。
  16. // @description:ja サイトのほとんどを殺すために渡し、あなたは、コピー切り取り、テキスト、右クリックメニューを選択することは禁止の制限を解除することができます。
  17.  
  18. // @homepageURL https://cat7373.github.io/remove-web-limits/
  19. // @supportURL https://github.com/Cat7373/remove-web-limits/issues/
  20.  
  21. // @author Cat73
  22. // @version 1.3
  23. // @license LGPLv3
  24.  
  25. // @compatible chrome Chrome_46.0.2490.86 + TamperMonkey + 脚本_1.3 测试通过
  26. // @compatible firefox Firefox_42.0 + GreaseMonkey + 脚本_1.2.1 测试通过
  27. // @compatible opera Opera_33.0.1990.115 + TamperMonkey + 脚本_1.1.3 测试通过
  28. // @compatible safari 未测试
  29.  
  30. // @match *://*/*
  31. // @grant none
  32. // @run-at document-start
  33. // ==/UserScript==
  34. (function() {
  35. 'use strict';
  36.  
  37. // 域名规则列表
  38. var rules = {
  39. black_rule: {
  40. name: "black",
  41. hook_eventNames: "",
  42. unhook_eventNames: ""
  43. },
  44. default_rule: {
  45. name: "default",
  46. hook_eventNames: "contextmenu|select|selectstart|copy|cut|dragstart",
  47. unhook_eventNames: "mousedown|mouseup|keydown|keyup",
  48. dom0: true,
  49. hook_addEventListener: true,
  50. hook_preventDefault: true,
  51. hook_set_returnValue: true,
  52. add_css: true
  53. }
  54. };
  55. // 域名列表
  56. var lists = {
  57. // 黑名单
  58. black_list: [
  59. /.*\.youtube\.com.*/,
  60. /.*\.wikipedia\.org.*/,
  61. /mail\.qq\.com.*/,
  62. /translate\.google\..*/
  63. ]
  64. };
  65.  
  66. // 要处理的 event 列表
  67. var hook_eventNames, unhook_eventNames, eventNames;
  68. // 储存名称
  69. var storageName = getRandStr('qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM', parseInt(Math.random() * 12 + 8));
  70. // 储存被 Hook 的函数
  71. var EventTarget_addEventListener = EventTarget.prototype.addEventListener;
  72. var document_addEventListener = document.addEventListener;
  73. var Event_preventDefault = Event.prototype.preventDefault;
  74.  
  75. // Hook addEventListener proc
  76. function addEventListener(type, func, useCapture) {
  77. var _addEventListener = this === document ? document_addEventListener : EventTarget_addEventListener;
  78. if(hook_eventNames.indexOf(type) >= 0) {
  79. _addEventListener.apply(this, [type, returnTrue, useCapture]);
  80. } else if(this && unhook_eventNames.indexOf(type) >= 0) {
  81. var funcsName = storageName + type + (useCapture ? 't' : 'f');
  82.  
  83. if(this[funcsName] === undefined) {
  84. this[funcsName] = [];
  85. _addEventListener.apply(this, [type, useCapture ? unhook_t : unhook_f, useCapture]);
  86. }
  87.  
  88. this[funcsName].push(func);
  89. } else {
  90. _addEventListener.apply(this, arguments);
  91. }
  92. }
  93.  
  94. // 清理循环
  95. function clearLoop() {
  96. var elements = getElements();
  97.  
  98. for(var i in elements) {
  99. for(var j in eventNames) {
  100. var name = 'on' + eventNames[j];
  101. if(elements[i][name] !== null && elements[i][name] !== onxxx) {
  102. if(unhook_eventNames.indexOf(eventNames[j]) >= 0) {
  103. elements[i][storageName + name] = elements[i][name];
  104. elements[i][name] = onxxx;
  105. } else {
  106. elements[i][name] = null;
  107. }
  108. }
  109. }
  110. }
  111. }
  112.  
  113. // 返回true的函数
  114. function returnTrue(e) {
  115. return true;
  116. }
  117. function unhook_t(e) {
  118. return unhook(e, this, storageName + e.type + 't');
  119. }
  120. function unhook_f(e) {
  121. return unhook(e, this, storageName + e.type + 'f');
  122. }
  123. function unhook(e, self, funcsName) {
  124. var list = self[funcsName];
  125. for(var i in list) {
  126. list[i](e);
  127. }
  128.  
  129. e.returnValue = true;
  130. return true;
  131. }
  132. function onxxx(e) {
  133. var name = storageName + 'on' + e.type;
  134. this[name](e);
  135.  
  136. e.returnValue = true;
  137. return true;
  138. }
  139.  
  140. // 获取随机字符串
  141. function getRandStr(chs, len) {
  142. var str = '';
  143.  
  144. while(len--) {
  145. str += chs[parseInt(Math.random() * chs.length)];
  146. }
  147.  
  148. return str;
  149. }
  150.  
  151. // 获取所有元素 包括document
  152. function getElements() {
  153. var elements = Array.prototype.slice.call(document.getElementsByTagName('*'));
  154. elements.push(document);
  155.  
  156. return elements;
  157. }
  158.  
  159. // 添加css
  160. function addStyle(css) {
  161. var style = document.createElement('style');
  162. style.innerHTML = css;
  163. document.head.appendChild(style);
  164. }
  165.  
  166. // 获取目标域名应该使用的规则
  167. function getRule(url) {
  168. function testUrl(list, url) {
  169. for(var i in list) {
  170. if(list[i].test(url)) {
  171. return true;
  172. }
  173. }
  174.  
  175. return false;
  176. }
  177.  
  178. if(testUrl(lists.black_list, url)) {
  179. return rules.black_rule;
  180. }
  181.  
  182. return rules.default_rule;
  183. }
  184.  
  185. // 初始化
  186. function init() {
  187. // 获取当前域名的规则
  188. var url = window.location.host + window.location.pathname;
  189. var rule = getRule(url);
  190.  
  191. // 设置 event 列表
  192. hook_eventNames = rule.hook_eventNames.split("|");
  193. // TODO Allowed to return value
  194. unhook_eventNames = rule.unhook_eventNames.split("|");
  195. eventNames = hook_eventNames.concat(unhook_eventNames);
  196.  
  197. // 调用清理 DOM0 event 方法的循环
  198. if(rule.dom0) {
  199. setInterval(clearLoop, 30 * 1000);
  200. setTimeout(clearLoop, 2500);
  201. window.addEventListener('load', clearLoop, true);
  202. clearLoop();
  203. }
  204.  
  205. // hook addEventListener
  206. if(rule.hook_addEventListener) {
  207. EventTarget.prototype.addEventListener = addEventListener;
  208. document.addEventListener = addEventListener;
  209. }
  210.  
  211. // hook preventDefault
  212. if(rule.hook_preventDefault) {
  213. Event.prototype.preventDefault = function() {
  214. if(eventNames.indexOf(this.type) < 0) {
  215. Event_preventDefault.apply(this, arguments);
  216. }
  217. };
  218. }
  219.  
  220. // Hook set returnValue
  221. if(rule.hook_set_returnValue) {
  222. Event.prototype.__defineSetter__('returnValue', function() {
  223. if(this.returnValue !== true && eventNames.indexOf(this.type) >= 0) {
  224. this.returnValue = true;
  225. }
  226. });
  227. }
  228.  
  229. console.debug('url: ' + url, 'storageName:' + storageName, 'rule: ' + rule.name);
  230.  
  231. // 添加CSS
  232. if(rule.add_css) {
  233. addStyle('html, * {-webkit-user-select:text!important; -moz-user-select:text!important; user-select:text!important; -ms-user-select:text!important; -khtml-user-select:text!important;}');
  234. }
  235. }
  236.  
  237. init();
  238. })();

QingJ © 2025

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