I have a html page with text content. On selecting any text and pressing the highlight button, I can change the style of the selected text to highlight the same. To implement th
The solution is really tricky. I somehow find a workaround. See my fiddle
function highlight() {
var range = window.getSelection().getRangeAt(0),
parent = range.commonAncestorContainer,
start = range.startContainer,
end = range.endContainer;
var startDOM = (start.parentElement == parent) ? start.nextSibling : start.parentElement;
var currentDOM = startDOM.nextElementSibling;
var endDOM = (end.parentElement == parent) ? end : end.parentElement;
//Process Start Element
highlightText(startDOM, 'START', range.startOffset);
while (currentDOM != endDOM && currentDOM != null) {
highlightText(currentDOM);
currentDOM = currentDOM.nextElementSibling;
}
//Process End Element
highlightText(endDOM, 'END', range.endOffset);
}
function highlightText(elem, offsetType, idx) {
if (elem.nodeType == 3) {
var span = document.createElement('span');
span.setAttribute('class', 'highlight');
var origText = elem.textContent, text, prevText, nextText;
if (offsetType == 'START') {
text = origText.substring(idx);
prevText = origText.substring(0, idx);
} else if (offsetType == 'END') {
text = origText.substring(0, idx);
nextText = origText.substring(idx);
} else {
text = origText;
}
span.textContent = text;
var parent = elem.parentElement;
parent.replaceChild(span, elem);
if (prevText) {
var prevDOM = document.createTextNode(prevText);
parent.insertBefore(prevDOM, span);
}
if (nextText) {
var nextDOM = document.createTextNode(nextText);
parent.appendChild(nextDOM);
}
return;
}
var childCount = elem.childNodes.length;
for (var i = 0; i < childCount; i++) {
if (offsetType == 'START' && i == 0)
highlightText(elem.childNodes[i], 'START', idx);
else if (offsetType == 'END' && i == childCount - 1)
highlightText(elem.childNodes[i], 'END', idx);
else
highlightText(elem.childNodes[i]);
}
}