jquery.caret

jquery caret plugin

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

  1. // ==UserScript==
  2. // @name jquery.caret
  3. // @namespace acdvorak
  4. // @description jquery caret plugin
  5. // @source https://github.com/acdvorak/jquery.caret
  6. // @copyright 2012-2014 Andrew C. Dvorak
  7. // @version 1.5.2
  8. // @license MIT
  9. // ==/UserScript==
  10.  
  11.  
  12. /*! jQuery Caret Plugin - v1.5.2 - 2014-03-25
  13. * https://github.com/acdvorak/jquery.caret
  14. * Copyright (c) 2012-2014 Andrew C. Dvorak; Licensed MIT */
  15. function loadjQueryCaret(){
  16. (function($, undefined) {
  17.  
  18. var _input = document.createElement('input');
  19.  
  20. var _support = {
  21. setSelectionRange: ('setSelectionRange' in _input) || ('selectionStart' in _input),
  22. createTextRange: ('createTextRange' in _input) || ('selection' in document)
  23. };
  24.  
  25. var _rNewlineIE = /\r\n/g,
  26. _rCarriageReturn = /\r/g;
  27.  
  28. var _getValue = function(input) {
  29. if (typeof(input.value) !== 'undefined') {
  30. return input.value;
  31. }
  32. return $(input).text();
  33. };
  34.  
  35. var _setValue = function(input, value) {
  36. if (typeof(input.value) !== 'undefined') {
  37. input.value = value;
  38. } else {
  39. $(input).text(value);
  40. }
  41. };
  42.  
  43. var _getIndex = function(input, pos) {
  44. var norm = _getValue(input).replace(_rCarriageReturn, '');
  45. var len = norm.length;
  46.  
  47. if (typeof(pos) === 'undefined') {
  48. pos = len;
  49. }
  50.  
  51. pos = Math.floor(pos);
  52.  
  53. // Negative index counts backward from the end of the input/textarea's value
  54. if (pos < 0) {
  55. pos = len + pos;
  56. }
  57.  
  58. // Enforce boundaries
  59. if (pos < 0) { pos = 0; }
  60. if (pos > len) { pos = len; }
  61.  
  62. return pos;
  63. };
  64.  
  65. var _hasAttr = function(input, attrName) {
  66. return input.hasAttribute ? input.hasAttribute(attrName) : (typeof(input[attrName]) !== 'undefined');
  67. };
  68.  
  69. /**
  70. * @class
  71. * @constructor
  72. */
  73. var Range = function(start, end, length, text) {
  74. this.start = start || 0;
  75. this.end = end || 0;
  76. this.length = length || 0;
  77. this.text = text || '';
  78. };
  79.  
  80. Range.prototype.toString = function() {
  81. return JSON.stringify(this, null, ' ');
  82. };
  83.  
  84. var _getCaretW3 = function(input) {
  85. return input.selectionStart;
  86. };
  87.  
  88. /**
  89. * @see http://stackoverflow.com/q/6943000/467582
  90. */
  91. var _getCaretIE = function(input) {
  92. var caret, range, textInputRange, rawValue, len, endRange;
  93.  
  94. // Yeah, you have to focus twice for IE 7 and 8. *cries*
  95. input.focus();
  96. input.focus();
  97.  
  98. range = document.selection.createRange();
  99.  
  100. if (range && range.parentElement() === input) {
  101. rawValue = _getValue(input);
  102.  
  103. len = rawValue.length;
  104.  
  105. // Create a working TextRange that lives only in the input
  106. textInputRange = input.createTextRange();
  107. textInputRange.moveToBookmark(range.getBookmark());
  108.  
  109. // Check if the start and end of the selection are at the very end
  110. // of the input, since moveStart/moveEnd doesn't return what we want
  111. // in those cases
  112. endRange = input.createTextRange();
  113. endRange.collapse(false);
  114.  
  115. if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
  116. caret = rawValue.replace(_rNewlineIE, '\n').length;
  117. } else {
  118. caret = -textInputRange.moveStart("character", -len);
  119. }
  120.  
  121. return caret;
  122. }
  123.  
  124. // NOTE: This occurs when you highlight part of a textarea and then click in the middle of the highlighted portion in IE 6-10.
  125. // There doesn't appear to be anything we can do about it.
  126. // alert("Your browser is incredibly stupid. I don't know what else to say.");
  127. // alert(range + '\n\n' + range.parentElement().tagName + '#' + range.parentElement().id);
  128.  
  129. return 0;
  130. };
  131.  
  132. /**
  133. * Gets the position of the caret in the given input.
  134. * @param {HTMLInputElement|HTMLTextAreaElement} input input or textarea element
  135. * @returns {Number}
  136. * @see http://stackoverflow.com/questions/263743/how-to-get-cursor-position-in-textarea/263796#263796
  137. */
  138. var _getCaret = function(input) {
  139. if (!input) {
  140. return undefined;
  141. }
  142.  
  143. // Mozilla, et al.
  144. if (_support.setSelectionRange) {
  145. return _getCaretW3(input);
  146. }
  147. // IE
  148. else if (_support.createTextRange) {
  149. return _getCaretIE(input);
  150. }
  151.  
  152. return undefined;
  153. };
  154.  
  155. var _setCaretW3 = function(input, pos) {
  156. input.setSelectionRange(pos, pos);
  157. };
  158.  
  159. var _setCaretIE = function(input, pos) {
  160. var range = input.createTextRange();
  161. range.move('character', pos);
  162. range.select();
  163. };
  164.  
  165. /**
  166. * Sets the position of the caret in the given input.
  167. * @param {HTMLInputElement|HTMLTextAreaElement} input input or textarea element
  168. * @param {Number} pos
  169. * @see http://parentnode.org/javascript/working-with-the-cursor-position/
  170. */
  171. var _setCaret = function(input, pos) {
  172. input.focus();
  173.  
  174. pos = _getIndex(input, pos);
  175.  
  176. // Mozilla, et al.
  177. if (_support.setSelectionRange) {
  178. _setCaretW3(input, pos);
  179. }
  180. // IE
  181. else if (_support.createTextRange) {
  182. _setCaretIE(input, pos);
  183. }
  184. };
  185.  
  186. /**
  187. * Inserts the specified text at the current caret position in the given input.
  188. * @param {HTMLInputElement|HTMLTextAreaElement} input input or textarea element
  189. * @param {String} text
  190. * @see http://parentnode.org/javascript/working-with-the-cursor-position/
  191. */
  192. var _insertAtCaret = function(input, text) {
  193. var curPos = _getCaret(input);
  194.  
  195. var oldValueNorm = _getValue(input).replace(_rCarriageReturn, '');
  196.  
  197. var newLength = +(curPos + text.length + (oldValueNorm.length - curPos));
  198. var maxLength = +input.getAttribute('maxlength');
  199.  
  200. if(_hasAttr(input, 'maxlength') && newLength > maxLength) {
  201. var delta = text.length - (newLength - maxLength);
  202. text = text.substr(0, delta);
  203. }
  204.  
  205. _setValue(input, oldValueNorm.substr(0, curPos) + text + oldValueNorm.substr(curPos));
  206.  
  207. _setCaret(input, curPos + text.length);
  208. };
  209.  
  210. var _getInputRangeW3 = function(input) {
  211. var range = new Range();
  212.  
  213. range.start = input.selectionStart;
  214. range.end = input.selectionEnd;
  215.  
  216. var min = Math.min(range.start, range.end);
  217. var max = Math.max(range.start, range.end);
  218.  
  219. range.length = max - min;
  220. range.text = _getValue(input).substring(min, max);
  221.  
  222. return range;
  223. };
  224.  
  225. /** @see http://stackoverflow.com/a/3648244/467582 */
  226. var _getInputRangeIE = function(input) {
  227. var range = new Range();
  228.  
  229. input.focus();
  230.  
  231. var selection = document.selection.createRange();
  232.  
  233. if (selection && selection.parentElement() === input) {
  234. var len, normalizedValue, textInputRange, endRange, start = 0, end = 0;
  235. var rawValue = _getValue(input);
  236.  
  237. len = rawValue.length;
  238. normalizedValue = rawValue.replace(/\r\n/g, "\n");
  239.  
  240. // Create a working TextRange that lives only in the input
  241. textInputRange = input.createTextRange();
  242. textInputRange.moveToBookmark(selection.getBookmark());
  243.  
  244. // Check if the start and end of the selection are at the very end
  245. // of the input, since moveStart/moveEnd doesn't return what we want
  246. // in those cases
  247. endRange = input.createTextRange();
  248. endRange.collapse(false);
  249.  
  250. if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
  251. start = end = len;
  252. } else {
  253. start = -textInputRange.moveStart("character", -len);
  254. start += normalizedValue.slice(0, start).split("\n").length - 1;
  255.  
  256. if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
  257. end = len;
  258. } else {
  259. end = -textInputRange.moveEnd("character", -len);
  260. end += normalizedValue.slice(0, end).split("\n").length - 1;
  261. }
  262. }
  263.  
  264. /// normalize newlines
  265. start -= (rawValue.substring(0, start).split('\r\n').length - 1);
  266. end -= (rawValue.substring(0, end).split('\r\n').length - 1);
  267. /// normalize newlines
  268.  
  269. range.start = start;
  270. range.end = end;
  271. range.length = range.end - range.start;
  272. range.text = normalizedValue.substr(range.start, range.length);
  273. }
  274.  
  275. return range;
  276. };
  277.  
  278. /**
  279. * Gets the selected text range of the given input.
  280. * @param {HTMLInputElement|HTMLTextAreaElement} input input or textarea element
  281. * @returns {Range}
  282. * @see http://stackoverflow.com/a/263796/467582
  283. * @see http://stackoverflow.com/a/2966703/467582
  284. */
  285. var _getInputRange = function(input) {
  286. if (!input) {
  287. return undefined;
  288. }
  289.  
  290. // Mozilla, et al.
  291. if (_support.setSelectionRange) {
  292. return _getInputRangeW3(input);
  293. }
  294. // IE
  295. else if (_support.createTextRange) {
  296. return _getInputRangeIE(input);
  297. }
  298.  
  299. return undefined;
  300. };
  301.  
  302. var _setInputRangeW3 = function(input, startPos, endPos) {
  303. input.setSelectionRange(startPos, endPos);
  304. };
  305.  
  306. var _setInputRangeIE = function(input, startPos, endPos) {
  307. var tr = input.createTextRange();
  308. tr.moveEnd('textedit', -1);
  309. tr.moveStart('character', startPos);
  310. tr.moveEnd('character', endPos - startPos);
  311. tr.select();
  312. };
  313.  
  314. /**
  315. * Sets the selected text range of (i.e., highlights text in) the given input.
  316. * @param {HTMLInputElement|HTMLTextAreaElement} input input or textarea element
  317. * @param {Number} startPos Zero-based index
  318. * @param {Number} endPos Zero-based index
  319. * @see http://parentnode.org/javascript/working-with-the-cursor-position/
  320. * @see http://stackoverflow.com/a/2966703/467582
  321. */
  322. var _setInputRange = function(input, startPos, endPos) {
  323. startPos = _getIndex(input, startPos);
  324. endPos = _getIndex(input, endPos);
  325.  
  326. // Mozilla, et al.
  327. if (_support.setSelectionRange) {
  328. _setInputRangeW3(input, startPos, endPos);
  329. }
  330. // IE
  331. else if (_support.createTextRange) {
  332. _setInputRangeIE(input, startPos, endPos);
  333. }
  334. };
  335.  
  336. /**
  337. * Replaces the currently selected text with the given string.
  338. * @param {HTMLInputElement|HTMLTextAreaElement} input input or textarea element
  339. * @param {String} text New text that will replace the currently selected text.
  340. * @see http://parentnode.org/javascript/working-with-the-cursor-position/
  341. */
  342. var _replaceInputRange = function(input, text) {
  343. var $input = $(input);
  344.  
  345. var oldValue = $input.val();
  346. var selection = _getInputRange(input);
  347.  
  348. var newLength = +(selection.start + text.length + (oldValue.length - selection.end));
  349. var maxLength = +$input.attr('maxlength');
  350.  
  351. if($input.is('[maxlength]') && newLength > maxLength) {
  352. var delta = text.length - (newLength - maxLength);
  353. text = text.substr(0, delta);
  354. }
  355.  
  356. // Now that we know what the user selected, we can replace it
  357. var startText = oldValue.substr(0, selection.start);
  358. var endText = oldValue.substr(selection.end);
  359.  
  360. $input.val(startText + text + endText);
  361.  
  362. // Reset the selection
  363. var startPos = selection.start;
  364. var endPos = startPos + text.length;
  365.  
  366. _setInputRange(input, selection.length ? startPos : endPos, endPos);
  367. };
  368.  
  369. var _selectAllW3 = function(elem) {
  370. var selection = window.getSelection();
  371. var range = document.createRange();
  372. range.selectNodeContents(elem);
  373. selection.removeAllRanges();
  374. selection.addRange(range);
  375. };
  376.  
  377. var _selectAllIE = function(elem) {
  378. var range = document.body.createTextRange();
  379. range.moveToElementText(elem);
  380. range.select();
  381. };
  382.  
  383. /**
  384. * Select all text in the given element.
  385. * @param {HTMLElement} elem Any block or inline element other than a form element.
  386. */
  387. var _selectAll = function(elem) {
  388. var $elem = $(elem);
  389. if ($elem.is('input, textarea') || elem.select) {
  390. $elem.select();
  391. return;
  392. }
  393.  
  394. // Mozilla, et al.
  395. if (_support.setSelectionRange) {
  396. _selectAllW3(elem);
  397. }
  398. // IE
  399. else if (_support.createTextRange) {
  400. _selectAllIE(elem);
  401. }
  402. };
  403.  
  404. var _deselectAll = function() {
  405. if (document.selection) {
  406. document.selection.empty();
  407. }
  408. else if (window.getSelection) {
  409. window.getSelection().removeAllRanges();
  410. }
  411. };
  412.  
  413. $.extend($.fn, {
  414.  
  415. /**
  416. * Gets or sets the position of the caret or inserts text at the current caret position in an input or textarea element.
  417. * @returns {Number|jQuery} The current caret position if invoked as a getter (with no arguments)
  418. * or this jQuery object if invoked as a setter or inserter.
  419. * @see http://web.archive.org/web/20080704185920/http://parentnode.org/javascript/working-with-the-cursor-position/
  420. * @since 1.0.0
  421. * @example
  422. * <pre>
  423. * // Get position
  424. * var pos = $('input:first').caret();
  425. * </pre>
  426. * @example
  427. * <pre>
  428. * // Set position
  429. * $('input:first').caret(15);
  430. * $('input:first').caret(-3);
  431. * </pre>
  432. * @example
  433. * <pre>
  434. * // Insert text at current position
  435. * $('input:first').caret('Some text');
  436. * </pre>
  437. */
  438. caret: function() {
  439. var $inputs = this.filter('input, textarea');
  440.  
  441. // getCaret()
  442. if (arguments.length === 0) {
  443. var input = $inputs.get(0);
  444. return _getCaret(input);
  445. }
  446. // setCaret(position)
  447. else if (typeof arguments[0] === 'number') {
  448. var pos = arguments[0];
  449. $inputs.each(function(_i, input) {
  450. _setCaret(input, pos);
  451. });
  452. }
  453. // insertAtCaret(text)
  454. else {
  455. var text = arguments[0];
  456. $inputs.each(function(_i, input) {
  457. _insertAtCaret(input, text);
  458. });
  459. }
  460.  
  461. return this;
  462. },
  463.  
  464. /**
  465. * Gets or sets the selection range or replaces the currently selected text in an input or textarea element.
  466. * @returns {Range|jQuery} The current selection range if invoked as a getter (with no arguments)
  467. * or this jQuery object if invoked as a setter or replacer.
  468. * @see http://stackoverflow.com/a/2966703/467582
  469. * @since 1.0.0
  470. * @example
  471. * <pre>
  472. * // Get selection range
  473. * var range = $('input:first').range();
  474. * </pre>
  475. * @example
  476. * <pre>
  477. * // Set selection range
  478. * $('input:first').range(15);
  479. * $('input:first').range(15, 20);
  480. * $('input:first').range(-3);
  481. * $('input:first').range(-8, -3);
  482. * </pre>
  483. * @example
  484. * <pre>
  485. * // Replace the currently selected text
  486. * $('input:first').range('Replacement text');
  487. * </pre>
  488. */
  489. range: function() {
  490. var $inputs = this.filter('input, textarea');
  491.  
  492. // getRange() = { start: pos, end: pos }
  493. if (arguments.length === 0) {
  494. var input = $inputs.get(0);
  495. return _getInputRange(input);
  496. }
  497. // setRange(startPos, endPos)
  498. else if (typeof arguments[0] === 'number') {
  499. var startPos = arguments[0];
  500. var endPos = arguments[1];
  501. $inputs.each(function(_i, input) {
  502. _setInputRange(input, startPos, endPos);
  503. });
  504. }
  505. // replaceRange(text)
  506. else {
  507. var text = arguments[0];
  508. $inputs.each(function(_i, input) {
  509. _replaceInputRange(input, text);
  510. });
  511. }
  512.  
  513. return this;
  514. },
  515.  
  516. /**
  517. * Selects all text in each element of this jQuery object.
  518. * @returns {jQuery} This jQuery object
  519. * @see http://stackoverflow.com/a/11128179/467582
  520. * @since 1.5.0
  521. * @example
  522. * <pre>
  523. * // Select the contents of span elements when clicked
  524. * $('span').on('click', function() { $(this).highlight(); });
  525. * </pre>
  526. */
  527. selectAll: function() {
  528. return this.each(function(_i, elem) {
  529. _selectAll(elem);
  530. });
  531. }
  532.  
  533. });
  534.  
  535. $.extend($, {
  536. /**
  537. * Deselects all text on the page.
  538. * @returns {jQuery} The jQuery function
  539. * @since 1.5.0
  540. * @example
  541. * <pre>
  542. * // Select some text
  543. * $('span').selectAll();
  544. *
  545. * // Deselect the text
  546. * $.deselectAll();
  547. * </pre>
  548. */
  549. deselectAll: function() {
  550. _deselectAll();
  551. return this;
  552. }
  553. });
  554.  
  555. }(window.jQuery || window.Zepto || window.$));
  556. }
  557. if (window.document.readyState === 'complete') {
  558. loadjQueryCaret();
  559. } else {
  560. window.addEventListener('load',loadjQueryCaret, false);
  561. }

QingJ © 2025

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