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;
}