0

My current solution is:

  1. Get selected html (include text and html tag), namely: selText
  2. highlightText = <span>selText</span>
  3. Find selText in innerHTML of the body or document (or the element which the mouse dragged in)
  4. Replace with highlightText

But if the document is: a a a a a a and user selects the last a. My function will highlight the first or all a.

Any suggestion?

Thank you.

Tuan Chau
  • 1,243
  • 1
  • 16
  • 30

1 Answers1

0

i think your question is duplicated, anyway i just searched the internet and found this article.

Below the final code to achieve what you ask

function highlightSelection()  {
  var selection;

  //Get the selected stuff
  if(window.getSelection) 
    selection = window.getSelection();
  else if(typeof document.selection!="undefined")
    selection = document.selection;

  //Get a the selected content, in a range object
  var range = selection.getRangeAt(0);

  //If the range spans some text, and inside a tag, set its css class.
  if(range && !selection.isCollapsed)
  {
    if(selection.anchorNode.parentNode == selection.focusNode.parentNode)
    {
      var span = document.createElement('span');
      span.className = 'highlight-green';
      range.surroundContents(span);
    }
  }
}

I also found this library rangy that is an helper you can use to select text but only works with jquery so i prefer the first vanilla-js solution.

var el = $("<span></span>");
el.text(rangy.getSelection().getRangeAt(0).toString());
rangy.getSelection().getRangeAt(0).deleteContents();
rangy.getSelection().getRangeAt(0).insertNode(el.get(0));
rangy.getSelection().getRangeAt(0).getSelection().setSingleRange(range);

On Range and User Selection

You have to select range using Document.createRange that return a Range object before you can use Range.surroundContents(), you could create a range this way.

var range = document.createRange();
range.setStart(startNode, startOffset);
range.setEnd(endNode, endOffset);

In practice you follow this guide to understand range and selection tecniques. The most important point is contained in this code

var userSelection;
if (window.getSelection) {
    userSelection = window.getSelection();
}
else if (document.selection) { // should come last; Opera!
    userSelection = document.selection.createRange();
}

After this you can use

userSelection.surroundContents()
Bolza
  • 1,904
  • 2
  • 17
  • 42
  • Yeah, your `highlightSelection` function works with `#textnode`. Unfortunately, the `surroundContents` doesn't work when I select like this: `this is a link`. With your suggestion, now I can get a list of user selected #textnode, but I don't know how to wrap / surround it into a highlight span. Anw, thank you so much. – Tuan Chau Nov 25 '14 at 01:07
  • I added more info to understand how to use surroundContents, you have to create a Range object from the userSelection before you can use that method. Please flag the answer as resolved if this solves your issue. – Bolza Nov 25 '14 at 10:53
  • Yeah, I will. I get the idea from your answer: process on `range` object, not on extracted text or htmlText. Thank you – Tuan Chau Nov 25 '14 at 16:52