1

I experience incorrect behavior of text selection which happens only in FF.

By clicking on bullet of li element FF displays selection spans across the whole li element but obtaining this selection range in JS results only in 1 character selected which is apparently incorrect.

Selecting text by dragging selection with mouse starting from text creates correct Range for current selection.

Live fiddle depicting issue here: http://jsfiddle.net/keaukraine/4ZE3a/

keaukraine
  • 5,315
  • 29
  • 54

2 Answers2

2

You're misinterpreting the range. A range boundary is expressed as an offset within a node; if that node is a text node then it's a character offset within that node's text. However, if the node is an element, the offset is the number of child nodes preceding the boundary, not a character offset. In this case, the selection range's start boundary is at offset 0 in the <li> element and the end boundary is at offset 1 in the <li> element. The <li> element only has one child node (a text node) so the range encompasses all of the element's content.

Tim Down
  • 318,141
  • 75
  • 454
  • 536
1

The other answer by Tim Down is right, here is the relevant documentation:

If the startContainer is a Node of type Text, Comment, or CDATASection, then the [startOffset] is the number of characters from the start of the startContainer to the boundary point of the Range. For other Node types, the startOffset is the number of child nodes between the start of the startContainer and the boundary point of the Range.

The problem is you can't detect that easily whether the element or the text node got clicked because nodes don't fire events. Here is a quick workaround:

Wrap the li content in span elements. Now you can check which element got selected and calculate the offsets accordingly.

<ul>
    <li>
        <span>first item</span>
    </li>
    <!-- ... -->
</ul>
var startOffset, endOffset;
if(e.target.tagName == 'LI') {
     startOffset = 0;
     endOffset = e.target.textContent.trim().length;
} else if(e.target.tagName == 'SPAN') {
    startOffset = range.startOffset;
    endOffset = range.endOffset;
}
kapex
  • 28,903
  • 6
  • 107
  • 121