Select text inside a link like Opera

Disable link dragging and select text.

当前为 2014-11-17 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Select text inside a link like Opera
  3. // @namespace eight04.blogspot.com
  4. // @description Disable link dragging and select text.
  5. // @include http://*
  6. // @include https://*
  7. // @version 4.0.9
  8. // @grant GM_addStyle
  9. // @run-at document-start
  10. // ==/UserScript==
  11.  
  12. "use strict";
  13.  
  14. function caretPositionFromPoint(x, y) {
  15. if (document.caretPositionFromPoint) {
  16. return document.caretPositionFromPoint(x, y);
  17. }
  18. var r = document.caretRangeFromPoint(x, y);
  19. return {
  20. offsetNode: r.startContainer,
  21. offset: r.startOffset
  22. };
  23. }
  24.  
  25. function inSelect(caretPos, selection){
  26. var i, len = selection.rangeCount, range;
  27. for (i = 0; i < len; i++) {
  28. range = selection.getRangeAt(i);
  29. if (range.isPointInRange(caretPos.offsetNode, caretPos.offset)) {
  30. return true;
  31. }
  32. }
  33. return false;
  34. }
  35.  
  36. var force = {
  37. target: null,
  38. select: getSelection(),
  39. currentPos: {
  40. x: null,
  41. y: null
  42. },
  43. startPos: {
  44. x: null,
  45. y: null
  46. },
  47. lastMouseDownPos: {
  48. x: null,
  49. y: null
  50. },
  51. handleEvent: function(e){
  52. var caretPos, a, movementX, movementY, select;
  53.  
  54. if (e.type == "click") {
  55.  
  56. if (e.ctrlKey || e.shiftKey || e.altKey || e.button) {
  57. return;
  58. }
  59.  
  60. if (
  61. this.uninitFlag ||
  62. e.pageX != this.lastMouseDownPos.x || // Fix Firefox clicking issue.
  63. e.pageY != this.lastMouseDownPos.y
  64. ) {
  65. e.preventDefault();
  66. e.stopImmediatePropagation();
  67. }
  68.  
  69. } else if (e.type == "mousedown") {
  70.  
  71. if (e.ctrlKey || e.shiftKey || e.altKey || e.button) {
  72. return;
  73. }
  74.  
  75. // Trak clicking to solve this:
  76. // https://gf.qytechs.cn/ru/forum/discussion/1898/doesn-t-work-on-some-sites
  77. this.lastMouseDownPos.x = e.pageX;
  78. this.lastMouseDownPos.y = e.pageY;
  79.  
  80. this.uninitFlag = false;
  81.  
  82. if (e.target.nodeName == "IMG") {
  83. this.imgFlag = true;
  84. }
  85.  
  86. select = window.getSelection();
  87. if (!select.isCollapsed) {
  88. caretPos = caretPositionFromPoint(e.pageX - window.scrollX, e.pageY - window.scrollY);
  89. if (!inSelect(caretPos, select)) {
  90. select.collapse(caretPos.offsetNode, caretPos.offset);
  91. }
  92. }
  93.  
  94. } else if (e.type == "mouseup") {
  95.  
  96. this.checkMove = false;
  97. this.imgFlag = false;
  98.  
  99. if (!this.target) {
  100. return;
  101. }
  102.  
  103. this.uninitFlag = true;
  104. this.uninit();
  105.  
  106. } else if (e.type == "mousemove") {
  107.  
  108. this.moveX = e.pageX - this.currentPos.x;
  109. this.moveY = e.pageY - this.currentPos.y;
  110. this.currentPos.x = e.pageX;
  111. this.currentPos.y = e.pageY;
  112.  
  113. if (!this.target) {
  114. return;
  115. }
  116.  
  117. select = window.getSelection();
  118. caretPos = caretPositionFromPoint(this.currentPos.x - window.scrollX, this.currentPos.y - window.scrollY);
  119. if (!this.multiSelect) {
  120. select.extend(caretPos.offsetNode, caretPos.offset);
  121. } else {
  122. this.range.setEnd(caretPos.offsetNode, caretPos.offset);
  123. }
  124.  
  125. } else if (e.type == "dragstart") {
  126.  
  127. if (e.button || e.altKey || e.shiftKey) {
  128. return;
  129. }
  130.  
  131. if (this.imgFlag) {
  132. this.imgFlag = false;
  133. return;
  134. }
  135.  
  136. a = e.target;
  137. while (a.nodeName != "A" && a.nodeName != "HTML") {
  138. a = a.parentNode;
  139. }
  140.  
  141. if (!a.href) {
  142. return;
  143. }
  144.  
  145. movementX = e.pageX - this.currentPos.x;
  146. movementY = e.pageY - this.currentPos.y;
  147.  
  148. if (!movementX && !movementY) {
  149. movementX = this.moveX;
  150. movementY = this.moveY;
  151. }
  152. if (Math.abs(movementX) < Math.abs(movementY)) {
  153. return;
  154. }
  155.  
  156. e.preventDefault();
  157. this.target = a;
  158. this.init(e);
  159. }
  160. },
  161. init: function(e){
  162. var select = window.getSelection();
  163.  
  164. this.startPos.x = e.pageX;
  165. this.startPos.y = e.pageY;
  166.  
  167. this.multiSelect = e.ctrlKey;
  168.  
  169. var caretPos = caretPositionFromPoint(this.startPos.x - window.scrollX, this.startPos.y - window.scrollY);
  170. if (!this.multiSelect) {
  171. select.collapse(caretPos.offsetNode, caretPos.offset);
  172. } else {
  173. this.range = new Range();
  174. this.range.setEnd(caretPos.offsetNode, caretPos.offset);
  175. this.range.collapse();
  176. select.addRange(this.range);
  177. }
  178.  
  179. this.target.classList.add("force-select");
  180.  
  181. },
  182. uninit: function(){
  183.  
  184. this.target.classList.remove("force-select");
  185. this.target = null;
  186. this.range = null;
  187. this.multiSelect = false;
  188.  
  189. }
  190. };
  191.  
  192. document.addEventListener("mousemove", force, false);
  193. document.addEventListener("mouseup", force, false);
  194. document.addEventListener("mousedown", force, false);
  195. document.addEventListener("click", force, true);
  196. document.addEventListener("dragstart", force, true);
  197. document.addEventListener("dragend", force, true);
  198. document.addEventListener("drag", force, true);
  199. document.addEventListener("DOMContentLoaded", function(){
  200. GM_addStyle(".force-select{ -moz-user-select: text!important; }");
  201. }, false);

QingJ © 2025

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