4

I need to get the position of the selected text within a content non-editable div (not a textarea, not a rtf editor, just a simple div)

I want to do this in order to enable users to select pieces of an article and "highlight it", by wrapping it in a span with a different background and, of course, an article is build with divs and/or p-s etc, not textareas or rtfs

Any ideas?

P.s. You can also use jQuery :D

P.s.s. I need the position of the selection, not the selection itself. Aka: it start from index I to index J. I need this because the normal method of finding the text in the parent does not always return a unique result, which would suck :)

Stefan
  • 3,962
  • 4
  • 34
  • 39
  • well if it were for jquery then it would have been a lot easier – S L Apr 07 '11 at 08:00
  • Index I and J relative to what? – Tim Down Apr 07 '11 at 08:41
  • The number of characters in the div I assume. – Calum Apr 07 '11 at 08:47
  • @tak3r: Even if you get numbers representing character indices of the selection within a div, this won't help you if the selection crosses multiple paragraphs, or starts and ends within different elements, because then wrapping a single `` around the selected text won't be possible. This is why I suggested `document.execCommand()`, which will take care of that for you. – Tim Down Apr 07 '11 at 10:28
  • yes, but just how cross-browsered is execCommand()? – Stefan Apr 07 '11 at 11:34
  • @tak3r: Supported in all the major browsers for several years. – Tim Down Apr 07 '11 at 13:21

5 Answers5

3

If you just want to change the background of the selected text, the easiest way to do this is by using document.execCommand(). See my answer here: Change CSS of selected text using Javascript

Community
  • 1
  • 1
Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • Tim's answer is clean and fast. But if you want to do some interactions with the highlighted ranges, without breaking the original text flow and mess up the dom tree, I would suggest calculating the absolute layouts of each selected line, and add an overlay inline-block. [See my answer here for details and examples](http://stackoverflow.com/a/43577515/290239). – lowatt Apr 23 '17 at 23:17
2
//Wrap selected text in span tags with the class 'hl'
//Take some action after (in this case, a simple alert)
$("p").live("mouseup",
    function() {
        selection = getSelectedText(); 
        if(selection.length >= 3) {
            $(this).html($(this).html().replace(selection, $('<\/span>').attr({'class':'hl'}).html(selection).parent().html()) );
            alert(selection);
        }       
    }
); 

//Grab selected text
function getSelectedText(){ 
    if(window.getSelection){ 
        return window.getSelection().toString(); 
    } 
    else if(document.getSelection){ 
        return document.getSelection(); 
    } 
    else if(document.selection){ 

        return document.selection.createRange().text; 
    } 
} 

Code comes from here: http://esbueno.noahstokes.com/post/92274686/highlight-selected-text-with-jquery

Calum
  • 5,308
  • 1
  • 22
  • 27
0

Well, even though you found a solution to the problem stated in your 2nd paragraph, i don't think the answer to your main question has been given. :)

The object Selection has a property named anchorOffset, giving exactly what you asked for (the position of the selected text within an element). The above link will tell you about which browsers support it, i'm afraid IE <9 might not.

function show_selected()
{
    var sel = selection();
    console.log(sel.anchorOffset + ':' + sel);
}

Now if you bind show_selected to, say, mouseup, you will see the offset and the selected text printed on the js console.

The fonction selection may be the following, supposed to be cross-browser:

function selection()
{
    var sel;
    if(window.getSelection){
      sel = window.getSelection()
    }
    else if(document.getSelection){
      sel = document.getSelection()
    }
    else if(document.selection){
      sel = document.selection.createRange()
    }
    return sel
}
0

You can check if text is selected by running :

window.getSelection and document.getSelection() and  document.selection 

(because browsers can check this i different ways) and then search for div containing this text .  

Alan
  • 622
  • 2
  • 6
  • 18
0

For getting the position of the selection, try these links:

http://bytes.com/topic/javascript/answers/153164-return-selectionstart-div

Set cursor position on contentEditable <div>

Community
  • 1
  • 1
Calum
  • 5,308
  • 1
  • 22
  • 27