Nikita Marinosian
Nikita Marinosian

Reputation: 797

Highlight text fragment selected by user

I have a <div>with some text<div> and I need to highlight the text fragment selected by a user.

I've partly implemented this: here is my code

thisRespondHightlightText(".container");


function thisRespondHightlightText(thisDiv){
    $(thisDiv).on("mouseup", function () {
        var selectedText = getSelectionText();
        var selectedTextRegExp = new RegExp(selectedText,"g");
        var text = $(this).text().replace(selectedTextRegExp, "<span class='highlight'>" + selectedText + "</span>");
        $(this).html(text);
    });
}

function getSelectionText() {
    var text = "";
    if (window.getSelection) {
        text = window.getSelection().toString();
    }
    return text;
}
.highlight {
    background-color: orange;
}
    
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</div>

However, I'm stuck with solving following problems:

  1. I need to highlight the exact fragment selected by user even if there a multiple matches in the text. For example, if user selects the second letter t in the <div>with some text<div>, only that t should be highlighted, not all of them or the first one.

issue1

  1. When user select the full text, it is not highlighted, but remains selected.

issue2

  1. How do I implement this for mobile? The problem is the mouseup event is not triggered.

Upvotes: 4

Views: 430

Answers (1)

zer00ne
zer00ne

Reputation: 43880

Update

Selection & Range API

The following demo uses the following:

Selection API
.getSelection()
.getRangeAt()
Range API
.extractContents()
.insertNode()
Miscellaneous
.createElement()
.appendChild()
.ctrlKey
.textContent
.tagName
.parentNode
.removeChild()
.createTextNode()

Just select text + ctrl (Mac: select text + ^) and it will wrap a <mark> tag around the selected text. To remove the highlight click + alt (Mac: click + )


Demo 1

Selection and Range API

function mark(e) {
  if (e.ctrlKey) {
    var sel = document.getSelection();
    var rng = sel.getRangeAt(0);
    var cnt = rng.extractContents();
    var node = document.createElement('MARK');
    node.style.backgroundColor = "orange";
    node.appendChild(cnt);
    rng.insertNode(node);
    sel.removeAllRanges();
  }
}

function unmark(e) {
  var cur = e.currentTarget;
  var tgt = e.target;
  if (tgt.tagName === 'MARK') {
    if (e.altKey) {
      var txt = tgt.textContent;
      tgt.parentNode.replaceChild(document.createTextNode(txt), tgt);
    }
  }
  cur.normalize();
}

document.addEventListener('keyup', mark); // ctrl+keyup
document.addEventListener('mouseup', mark);// ctrl+mouseup
document.addEventListener('click', unmark); // alt+click
::selection {
  background: orange
}
<P>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
  in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</P>


::selection

Try the pseudo-element ::selection


Demo 2

::selection {
  background: orange;
}
<P>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
  in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</P>

Upvotes: 3

Related Questions