Satisfactory selection of text not working

I ran the following: when I try to select the text in the element contenteditable, and the end of the selection - is the beginning of an element's content, then no selection event does not start, and there is Selection, and Rangeobjects.

Can someone please give me any advice on why this might happen or how I can prevent it?

Code responsible for obtaining the selection range:

$('div[contenteditable="true"]').bind("mouseup keyup touchend", function() {
  lastCaretIndex = getSelectionRange();
});

function getSelectionRange() {
  var sel;
  if (window.getSelection) {
    sel = window.getSelection();

    console.log(sel); // this doesn't print anything event empty string

    if (sel.rangeCount) {
      return sel.getRangeAt(0);
    }
  } else if (document.selection) {
    return document.createRange();
  }

  return null;
}
<div id="main-input" contenteditable="true">Hello world!</div>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
Run codeHide result

JSFiddle (open your browser console to make sure the selection is not logged).

GIF illustrating steps to reproduce the problem

+4
source share
2 answers

, , contenteditable. ,

$('div[contenteditable="true"]').bind("mouseup keyup touchend", // ...

, mouseup . , . div ( !), div mouseup , , .

:

document.addEventListener('selectionchange', function(event) {
  console.log(event.type);
});
<div contenteditable="true">Hello world!</div>
Hide result

, , . , , throttle .

.

function handler() {
  // do whatever you want here
  // this shows the selection and all ranges it consists of
  var sel = window.getSelection(),
      ranges = Array(sel.rangeCount).fill(0).map((_, i) => sel.getRangeAt(i));
  ranges = ranges.map((r) => `${r.startOffset}-${r.endOffset}`).join(';');
  console.log(`Selection [${ranges}:"${sel.toString()}"]`);
}

function throttle(func) {
  var timeoutId = false,
      called = false,
      wrap = function() {
        if (!called) {
          clearInterval(timeoutId);
          timeoutId = false;
        } else {
          func();
        }
        called = false;
      };
  return function() {
    if (timeoutId === false) {
      func();
      timeoutId = setInterval(wrap, 500);
    } else {
      called = true;
    }
  };
}

document.addEventListener('selectionchange', throttle(handler));
<div contenteditable="true">Hello world!</div>
Hide result
+5

, - .

, Selection , object, Selection .

, Selection.toString(), , :

$('div[contenteditable="true"]').bind("mouseup keyup touchend", function() {
  lastCaretIndex = getSelectionRange();
});

function getSelectionRange() {
  var sel;
  if (window.getSelection) {
    sel = window.getSelection();

    console.log(sel.toString()); // this doesn't print anything event empty string

    if (sel.rangeCount) {
      return sel.getRangeAt(0);
    }
  } else if (document.selection) {
    return document.createRange();
  }

  return null;
}
<div id="main-input" contenteditable="true">Hello world!</div>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
Hide result

, .

+1

Source: https://habr.com/ru/post/1673698/


All Articles