3

I've the following div:

<div id="target" >hello(first), hello(second), hello(third), hello(fourth)</div>

and following code based on this discussion:

    $(document).ready(function(){
      $('#target').bind('mouseup', function(){
           var needle = window
            .getSelection()
            .getRangeAt(0);
           var haystack = $(this).text();
           var newText = haystack.replace(needle,'<span class="highlight">' + needle + '</span>');
           $(this).html(newText);             
      });   

When I select one of the "hello", it 'randomly' highlights one of them rather than the actual selected "hello".

How can I highlight the selected one?

Thanks in advance for your help.

Community
  • 1
  • 1
pion
  • 3,593
  • 6
  • 29
  • 41

1 Answers1

1

Here is something which seems to work well :

$('#target').bind('mouseup', function(){
    var needle = window.getSelection().getRangeAt(0);
    var start = window.getSelection().anchorOffset;
    var end = window.getSelection().focusOffset;
    var haystack = $(this).text();
    var startHighlight = '<span class="highlight">';
    var endHighlight = '</span>';
    var nodeContent = window.getSelection().anchorNode.textContent;

    // If the selection goes backward, switch indexes
    if (end < start)
    {
        var tmp = start;
        start = end;
        end = tmp;
    }

    // If there is a span
    if ($('span', this).size() > 0)
    {
        // If the selection starts after the span, compute an offset for start and end
        if (haystack.substr(0, nodeContent.length) != nodeContent)
        {
            var diff = $(this).html().indexOf(startHighlight) + $('span', this).text().length;
            start += diff;
            end += diff;
        }

        // Remove the span
        var spanText = $('span', this).contents().filter(textNodeFilter);
        $(spanText).unwrap();
    }

    var newText = haystack.substring(start, end).replace(needle, startHighlight + needle + endHighlight);
    haystack = haystack.substring(0, start) + newText + haystack.substring(end);

    $(this).html(haystack);
});
Romain Guidoux
  • 2,943
  • 4
  • 28
  • 48
  • Be aware that the selection object for Google Chrome does not expose `anchorOffset` etc. Looks like it is hard to write a cross-browser solution for this. – Tomalak Jun 13 '11 at 13:53