3

My requirement is to get the start and end character index of the text selected by the user with respect to the main div, lets say "content" div. See sample code below. But when I select the "Rich" word in the web view. Its start and end character index comes respective to the where the "span" tag i.e. 1 and 5, respectively. Whereas it should be 12 and 16 w.r.t "content" div.

<html>
<body>
    <div id="content" contenteditable="true" style="font-family: Times New Roman; color: #fff; font-size: 18;">
          This is <span style="background-color: yellow;">out</span> Rich Text Editing View
    </div>
</body>

JavaScript function m using at the moment is

function getHighlightedString()
{
    var text = document.getSelection();
    startIndex = text.anchorOffset;
    endIndex = text.focusOffset;
    selectedText = text.anchorNode.textContent.substr(startIndex, endIndex - text.anchorOffset);
}

Please help me out.

Harshit Gupta
  • 1,200
  • 12
  • 27

1 Answers1

8

Here's an answer adapted from this one. The same caveats from that answer apply.

Demo: http://jsfiddle.net/62Bcf/1/

Code:

function getSelectionCharacterOffsetsWithin(element) {
    var startOffset = 0, endOffset = 0;
    if (typeof window.getSelection != "undefined") {
        var range = window.getSelection().getRangeAt(0);
        var preCaretRange = range.cloneRange();
        preCaretRange.selectNodeContents(element);
        preCaretRange.setEnd(range.startContainer, range.startOffset);
        startOffset = preCaretRange.toString().length;
        endOffset = startOffset + range.toString().length;
    } else if (typeof document.selection != "undefined" &&
               document.selection.type != "Control") {
        var textRange = document.selection.createRange();
        var preCaretTextRange = document.body.createTextRange();
        preCaretTextRange.moveToElementText(element);
        preCaretTextRange.setEndPoint("EndToStart", textRange);
        startOffset = preCaretTextRange.text.length;
        endOffset = startOffset + textRange.text.length;
    }
    return { start: startOffset, end: endOffset };
}
Community
  • 1
  • 1
Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • thanks for the quick response, @tim. I already tried your answer before. But it does not give the right answer. for the above code, for the "out" respective offsets are 11 and 14 and for "Rich" its is 16 and 20. which is not correct. – Harshit Gupta Feb 07 '13 at 12:49
  • 1
    @harshitgupta: The reason for that is that all white space in all text nodes is counting towards the total offset. If you want character offsets that ignore unrendered white space, you'll need a more complicated approach, such as my own [Rangy TextRange module](http://code.google.com/p/rangy/wiki/TextRangeModule). A simpler workaround would be to remove the whitespace preceding the start of the text inside your editable element. Also, there was an error in my code which I've just updated. – Tim Down Feb 07 '13 at 12:57
  • 1
    @TimDown I have read your 100 answers in 3 days and dude you are awesome. I will work free for you just let me know :P – therealprashant Dec 23 '15 at 04:49