Range and Caret position doesn't match

2019-07-04 03:35发布

I noticed this problem in MS Edge, the caret position and range doesn't match up or wrong inside a content editable.

$("#c").click(function(e) {
  var sel = window.getSelection();
  var range = sel.getRangeAt(0);
 
  $("#res").get(0).textContent = "START_OFFSET:" + range.startOffset + "->" + range.startContainer.innerHTML;
  console.log("Range count: " + sel.rangeCount);
});
<html>

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
</head>

<body>
  <div id="c" contenteditable="true">
    <span>TEST</span>
  </div>
  <span id="res"></span>
</body>

</html>

In case if it is a hassle to open MS Edge, here's the snippet :

enter image description here

The result should be 4 -> TEST

Weird enough, the actual caret is pointing at the span node which contains an innerHTML of TEST but the start offset and end offset are showing 1. By the range data it is like this |TEST but visually it is TEST|.

Is there a way in solving this?

Via JS, I can't seem to catch the correct information inside the range class to adjust properly the startOffset and endOffset unless I detect the nearest letter near the click location and insert the caret there, but I believe it's tedious.

I found this. is there any follow up regarding to a solution? Thanks.

Update

The span element is interfering with the range.

$("#c").click(function(e) {
  var sel = window.getSelection();
  var range = sel.getRangeAt(0);
 
  $("#res").get(0).textContent = "START_OFFSET:" + range.startOffset + "-> " + range.startContainer.innerHTML;
 console.log(range.startContainer);
});
<html>

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
</head>

<body>
  <div id="c" contenteditable="true">
    TEST
  </div>
  <span id="res"></span>
</body>

</html>

1条回答
劳资没心,怎么记你
2楼-- · 2019-07-04 03:55

I've narrowed down the problem and the <span> is the root of all evil.

The spans text is wrapped inside a text element, in which you are navigating ([Object Text], check the startContainer property). After the last char, the text element ends, the span however does not. So you're now after the text element (index 0) and at the first index in the span. Other major browsers do not have this problem, because the text element continues after the last character. This is most likely an Edge bug.

Remove the span to solve the problem.

查看更多
登录 后发表回答