Great Day Today
Great Day Today

Reputation: 91

How to highlight text based on caret position?

I want to have a button that adds a highlight to the currently selected text. I plan on doing this with the caret position of the selection. I have the following code:

function getCaretCharacterOffsetWithin(element) {
    var caretOffset = 0;
    var doc = element.ownerDocument || element.document;
    var win = doc.defaultView || doc.parentWindow;
    var sel;
    if (typeof win.getSelection != "undefined") {
        sel = win.getSelection();
        if (sel.rangeCount > 0) {
            var range = win.getSelection().getRangeAt(0);
            var preCaretRange = range.cloneRange();
            preCaretRange.selectNodeContents(element);
            preCaretRange.setEnd(range.endContainer, range.endOffset);
            caretOffset = preCaretRange.toString().length;
        }
    } else if ( (sel = doc.selection) && sel.type != "Control") {
        var textRange = sel.createRange();
        var preCaretTextRange = doc.body.createTextRange();
        preCaretTextRange.moveToElementText(element);
        preCaretTextRange.setEndPoint("EndToEnd", textRange);
        caretOffset = preCaretTextRange.text.length;
    }
    return caretOffset;
}

function showCaretPos() {
    var el = document.getElementById("test");
    var caretPosEl = document.getElementById("caretPos");
    caretPosEl.innerHTML = "Caret position: " + getCaretCharacterOffsetWithin(el);
}

document.body.onkeyup = showCaretPos;
document.body.onmouseup = showCaretPos;
Non-editable text. Editable is below:
<div id="test" contenteditable="true">Hello, some <b>bold</b> and <i>italic and <b>bold</b></i> text</div>
<div id="caretPos"></div>

The above code finds the caret position. How can I now use the caret position to highlight only that position of text.

Possible Idea Get caret position from above and now substr() to add highlight. str.substr(above caret position).

What is the best way to accomplish this?

EDIT

I don't want to change the color selection. I only want to use the caret position to then add a div that acts as a highlighter. For example:

Hi, my name is Bob.

Now, I use the caret position to track the position for only my text selection. Now, I replace the text with the original text but also with a div for the text selection.

Let's say I want highlight the phrase name is. I'm using this method of using caret position to not highlight every instance of this phrase. Only the exact position of where the phrase is. For example, let's my text has the phrase name is twice, it will only highlight the phrase that matches the caret position. Then, replace the text with something like: <div id='highlight'> name is </div>

Upvotes: 4

Views: 826

Answers (1)

zer00ne
zer00ne

Reputation: 43870

In the following Snippet are 2 functions that do the same thing except that the first one uses a <span> and the second one uses a <div>. What the functions do is essentially...

  1. ...removes the selected content (text)...
  2. ...creates a <span> or <div>...
  3. ...sets the backgroundColor to yellow...
  4. ...the content is then appended to the <span/div>...
  5. ...then finally the <span/div> is inserted into the range.

The <span> as you can see is probably a better choice. Using a <div> is just plain messy.

SNIPPET

var spanEdit = document.getElementById('spanEdit');
var divEdit = document.getElementById('divEdit');

function highlightSpan() {
  var range = document.getSelection().getRangeAt(0);
  var contents = range.extractContents();
  var node = document.createElement('span');
  node.style.backgroundColor = "yellow";
  node.appendChild(contents);
  range.insertNode(node);
}

function highlightDiv() {
  var range = document.getSelection().getRangeAt(0);
  var contents = range.extractContents();
  var node = document.createElement('div');
  node.style.backgroundColor = "yellow";
  node.appendChild(contents);
  range.insertNode(node);
}

spanEdit.onkeyup = highlightSpan;
spanEdit.onmouseup = highlightSpan;

divEdit.onkeyup = highlightDiv;
divEdit.onmouseup = highlightDiv;
<div id='spanEdit' contenteditable="true">Highlight inserted span. This uses extractContents() method.</div>
<div>&nbsp;</div>
<div id='divEdit' contenteditable="true">Highlight inserted div. This uses extractContents() method.</div>

The functions are an adaptation from this post

Upvotes: 1

Related Questions