jquery highlighter

Required for another script

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.gf.qytechs.cn/scripts/4229/13465/jquery%20highlighter.js

  1. // ==UserScript==
  2. // @name jquery highlighter
  3. // @version 1.0
  4. // ==/UserScript==
  5.  
  6. /* global jQuery */
  7.  
  8. /*
  9. * Highlighter.js 1.0
  10. *
  11. * Author: Matthew Conlen <matt.conlen@huffingtonpost.com>
  12. * Huffington Post Labs
  13. *
  14. * Copyright 2012: Huffington Post Labs
  15. *
  16. * This program is free software. It comes without any warranty, to
  17. * the extent permitted by applicable law. You can redistribute it
  18. * and/or modify it under the terms of the WTFPL, Version 2, as
  19. * published by Sam Hocevar. See http://sam.zoy.org/wtfpl/
  20. * for more details.
  21. */
  22.  
  23. (function ($) {
  24. /*
  25. * Code for triple click from
  26. * http://css-tricks.com/snippets/jquery/triple-click-event/
  27. */
  28. $.event.special.tripleclick = {
  29.  
  30. setup: function (data, namespaces) {
  31. var elem = this,
  32. $elem = jQuery(elem);
  33. $elem.bind('click', jQuery.event.special.tripleclick.handler);
  34. },
  35.  
  36. teardown: function (namespaces) {
  37. var elem = this,
  38. $elem = jQuery(elem);
  39. $elem.unbind('click', jQuery.event.special.tripleclick.handler);
  40. },
  41.  
  42. handler: function (event) {
  43. var elem = this,
  44. $elem = jQuery(elem),
  45. clicks = $elem.data('clicks') || 0;
  46. clicks += 1;
  47. if (clicks === 3) {
  48. clicks = 0;
  49.  
  50. // set event type to "tripleclick"
  51. event.type = "tripleclick";
  52.  
  53. // let jQuery handle the triggering of "tripleclick" event handlers
  54. jQuery.event.dispatch.apply(this, arguments);
  55. }
  56. $elem.data('clicks', clicks);
  57. }
  58. };
  59.  
  60. /*
  61. * Attempt to get the previous sibling
  62. * of a container in the event of a triple
  63. * click.
  64. *
  65. * Adapted from http://stackoverflow.com/a/574922
  66. */
  67. function get_previoussibling(n) {
  68. var y = n, x;
  69. try {
  70. x = n.previousSibling;
  71. while (x && x.nodeType != 1) {
  72. y = x;
  73. x = x.previousSibling;
  74. }
  75. } catch (err) {
  76. console.log(err);
  77. topOffset = -15;
  78. return y;
  79. }
  80. return x ? x : y;
  81. }
  82.  
  83. var methods = {
  84. init: function (options) {
  85.  
  86. var settings = $.extend({
  87. 'selector': '.highlighter-container',
  88. 'minWords': 0,
  89. 'complete': function() {}
  90. }, options);
  91. var numClicks = 0;
  92. var topOffset = 0;
  93. var leftOffset = 0;
  94. var isDown = false;
  95.  
  96. var selText;
  97.  
  98. return this.each(function () {
  99. /*
  100. * Insert an html <span> after a user selects text.
  101. * We then use the X-Y coordinates of that span
  102. * to place our tooltip.
  103. * Thanks to http://stackoverflow.com/a/3599599 for
  104. * some inspiration.
  105. */
  106. function insertSpanAfterSelection(clicks) {
  107. var html = "<span class='dummy'><span>";
  108. topOffset = 0;
  109. leftOffset = 0;
  110. if (numClicks !== clicks) return;
  111. var isIE = (navigator.appName === "Microsoft Internet Explorer");
  112. var sel, range, expandedSelRange, node;
  113. var position;
  114. if (window.getSelection) {
  115. sel = window.getSelection();
  116. selText = sel.toString();
  117.  
  118. if ($.trim(selText) === '' || selText.split(' ').length < settings.minWords) return;
  119.  
  120. if (sel.getRangeAt && sel.rangeCount) {
  121. range = window.getSelection().getRangeAt(0);
  122.  
  123. expandedSelRange = range.cloneRange();
  124. expandedSelRange.collapse(false);
  125.  
  126. // Range.createContextualFragment() would be useful here but is
  127. // non-standard and not supported in all browsers (IE9, for one)
  128. var el = document.createElement("div");
  129. el.innerHTML = html;
  130. var dummy = document.createElement("span");
  131.  
  132. if (range.startOffset === 0 && range.endOffset === 0) {
  133.  
  134. var cont = expandedSelRange.startContainer;
  135. var prev = get_previoussibling(cont);
  136. try {
  137. expandedSelRange.selectNode(prev.lastChild);
  138. } catch (err) {
  139. leftOffset = 40;
  140. topOffset = -15;
  141. expandedSelRange.selectNode(prev);
  142. }
  143. // console.log(expandedSelRange);
  144. expandedSelRange.collapse(false);
  145. } else if(range.endOffset === 0 ) {
  146. topOffset = -25;
  147. leftOffset = 40;
  148. }
  149.  
  150.  
  151. if (numClicks !== clicks) return;
  152. $(settings.selector).hide();
  153. if (!isIE && $.trim(selText) === $.trim(expandedSelRange.startContainer.innerText)) {
  154. expandedSelRange.startContainer.innerHTML += "<span class='dummy'>&nbsp;</span>";
  155. position = $(".dummy").offset();
  156. $(".dummy").remove();
  157. } else if (!isIE && $.trim(selText) === $.trim(expandedSelRange.endContainer.innerText)) {
  158. expandedSelRange.endContainer.innerHTML += "<span class='dummy'>&nbsp;</span>";
  159. position = $(".dummy").offset();
  160. $(".dummy").remove();
  161. } else {
  162. expandedSelRange.insertNode(dummy);
  163. position = $(dummy).offset();
  164. dummy.parentNode.removeChild(dummy);
  165. }
  166. }
  167. } else if (document.selection && document.selection.createRange) {
  168. range = document.selection.createRange();
  169. expandedSelRange = range.duplicate();
  170.  
  171. selText = expandedSelRange.text;
  172. if ($.trim(selText) === '' || selText.split(' ').length < settings.minWords) return;
  173.  
  174. range.collapse(false);
  175. range.pasteHTML(html);
  176.  
  177. expandedSelRange.setEndPoint("EndToEnd", range);
  178. expandedSelRange.select();
  179. position = $(".dummy").offset();
  180. $(".dummy").remove();
  181. }
  182.  
  183. $(settings.selector).css("top", position.top + topOffset + "px");
  184. $(settings.selector).css("left", position.left + leftOffset + "px");
  185. $(settings.selector).show(300, function() {
  186. settings.complete(selText);
  187. });
  188. }
  189. $(settings.selector).hide();
  190. $(settings.selector).css("position", "absolute");
  191. $(document).bind('mouseup.highlighter', function (e) {
  192. if (isDown) {
  193. numClicks = 1;
  194. clicks = 0;
  195. setTimeout(function () {
  196. insertSpanAfterSelection(1);
  197. }, 300);
  198. isDown = false;
  199. }
  200. });
  201. $(this).bind('mouseup.highlighter', function (e) {
  202. numClicks = 1;
  203. clicks = 0;
  204. setTimeout(function () {
  205. insertSpanAfterSelection(1);
  206. }, 300);
  207. });
  208. $(this).bind('tripleclick.highlighter', function (e) {
  209. numClicks = 3;
  210. setTimeout(function () {
  211. insertSpanAfterSelection(3);
  212. }, 200);
  213. });
  214.  
  215. $(this).bind('dblclick.highlighter', function (e) {
  216. numClicks = 2;
  217. setTimeout(function () {
  218. insertSpanAfterSelection(2);
  219. }, 300);
  220. });
  221. $(this).bind('mousedown.highlighter', function (e) {
  222. $(settings.selector).hide();
  223. isDown = true;
  224. });
  225.  
  226. });
  227. },
  228. destroy: function (content) {
  229. return this.each(function () {
  230. $(document).unbind('mouseup.highlighter');
  231. $(this).unbind('mouseup.highlighter');
  232. $(this).unbind('tripleclick.highlighter');
  233. $(this).unbind('dblclick.highlighter');
  234. $(this).unbind('mousedown.highlighter');
  235. });
  236. }
  237. };
  238.  
  239. /*
  240. * Method calling logic taken from the
  241. * jQuery article on best practices for
  242. * plugins.
  243. *
  244. * http://docs.jquery.com/Plugins/Authoring
  245. */
  246. $.fn.highlighter = function (method) {
  247. if (methods[method]) {
  248. return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
  249. } else if (typeof method === 'object' || !method) {
  250. return methods.init.apply(this, arguments);
  251. } else {
  252. $.error('Method ' + method + ' does not exist on jQuery.highlighter');
  253. }
  254.  
  255. };
  256.  
  257. })(jQuery);

QingJ © 2025

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