pizhu-cursor.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. console.info("cursor");
  2. // 为div保存range
  3. var _range = null;
  4. function displayAreaFocusAndBlur() {
  5. // 如果有保存的焦点则重新获取到该焦点,如果没有保存的焦点则以文本最后为该焦点
  6. $('#displayArea').on('focus', function(ev) {
  7. var selection = window.getSelection();
  8. if (selection && _range) {
  9. selection.removeAllRanges();
  10. selection.addRange(_range); // 添加焦点
  11. } else {
  12. var displayArea = document.getElementById('displayArea');
  13. cursorManager.setEndOfContenteditable(displayArea);
  14. }
  15. });
  16. // 保存焦点到_range
  17. $('#displayArea').on('blur', function() {
  18. var selection = window.getSelection();
  19. if (selection && selection.rangeCount > 0) {
  20. _range = selection.getRangeAt(0).cloneRange();
  21. }
  22. });
  23. }
  24. // 保证focus时,光标定位到元素的最后面
  25. // Namespace management idea from
  26. // http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/
  27. function cursorManage(cursorManager) {
  28. // From: http://www.w3.org/TR/html-markup/syntax.html#syntax-elements
  29. var voidNodeTags = [ 'AREA', 'BASE', 'BR', 'COL', 'EMBED', 'HR', 'IMG',
  30. 'INPUT', 'KEYGEN', 'LINK', 'MENUITEM', 'META', 'PARAM', 'SOURCE',
  31. 'TRACK', 'WBR', 'BASEFONT', 'BGSOUND', 'FRAME', 'ISINDEX' ];
  32. // From:
  33. // http://stackoverflow.com/questions/237104/array-containsobj-in-javascript
  34. Array.prototype.contains = function(obj) {
  35. var i = this.length;
  36. while (i--) {
  37. if (this[i] === obj) {
  38. return true;
  39. }
  40. }
  41. return false;
  42. }
  43. // Basic idea from:
  44. // http://stackoverflow.com/questions/19790442/test-if-an-element-can-contain-text
  45. function canContainText(node) {
  46. if (node.nodeType == 1) { // is an element node
  47. return !voidNodeTags.contains(node.nodeName);
  48. } else { // is not an element node
  49. return false;
  50. }
  51. }
  52. function getLastChildElement(el) {
  53. var lc = el.lastChild;
  54. while (lc && lc.nodeType != 1) {
  55. if (lc.previousSibling)
  56. lc = lc.previousSibling;
  57. else
  58. break;
  59. }
  60. return lc;
  61. }
  62. // Based on Nico Burns's answer
  63. cursorManager.setEndOfContenteditable = function(contentEditableElement) {
  64. while (getLastChildElement(contentEditableElement)
  65. && canContainText(getLastChildElement(contentEditableElement))) {
  66. contentEditableElement = getLastChildElement(contentEditableElement);
  67. }
  68. var range, selection;
  69. if (document.createRange) // Firefox, Chrome, Opera, Safari, IE 9+
  70. {
  71. range = document.createRange(); // Create a range (a range is a like
  72. // the selection but invisible)
  73. range.selectNodeContents(contentEditableElement); // Select the
  74. // entire
  75. // contents of
  76. // the element
  77. // with the
  78. // range
  79. range.collapse(false); // collapse the range to the end point.
  80. // false means collapse to end rather than
  81. // the start
  82. selection = window.getSelection(); // get the selection object
  83. // (allows you to change
  84. // selection)
  85. selection.removeAllRanges(); // remove any selections already
  86. // made
  87. _range = range.cloneRange();
  88. selection.addRange(range); // make the range you have just created
  89. // the visible selection
  90. } else if (document.selection) // IE 8 and lower
  91. {
  92. range = document.body.createTextRange(); // Create a range (a
  93. // range is a like the
  94. // selection but
  95. // invisible)
  96. range.moveToElementText(contentEditableElement); // Select the
  97. // entire
  98. // contents of
  99. // the element
  100. // with the
  101. // range
  102. range.collapse(false); // collapse the range to the end point.
  103. // false means collapse to end rather than
  104. // the start
  105. range.select(); // Select the range (make it the visible selection
  106. }
  107. }
  108. cursorManager.setEndOfRange = function(range) {
  109. if (document.createRange) {
  110. range.collapse(false);
  111. selection = window.getSelection();
  112. selection.removeAllRanges();
  113. _range = range.cloneRange();
  114. selection.addRange(range);
  115. }
  116. }
  117. }