How can I highlight the text of the DOM Range object?
I would suggest using document
's or the TextRange
's execCommand
method, which is built for just such a purpose, but is usually used in editable documents. Here's the answer I gave to a similar question:
The following should do what you want. In non-IE browsers it turns on designMode, applies a background colour and then switches designMode off again.
UPDATE
Fixed to work in IE 9.
UPDATE 12 September 2013
Here's a link detailing a method for removing highlights created by this method:
https://stackoverflow.com/a/8106283/96100
function makeEditableAndHighlight(colour) {
var range, sel = window.getSelection();
if (sel.rangeCount && sel.getRangeAt) {
range = sel.getRangeAt(0);
}
document.designMode = "on";
if (range) {
sel.removeAllRanges();
sel.addRange(range);
}
// Use HiliteColor since some browsers apply BackColor to the whole block
if (!document.execCommand("HiliteColor", false, colour)) {
document.execCommand("BackColor", false, colour);
}
document.designMode = "off";
}
function highlight(colour) {
var range;
if (window.getSelection) {
// IE9 and non-IE
try {
if (!document.execCommand("BackColor", false, colour)) {
makeEditableAndHighlight(colour);
}
} catch (ex) {
makeEditableAndHighlight(colour)
}
} else if (document.selection && document.selection.createRange) {
// IE <= 8 case
range = document.selection.createRange();
range.execCommand("BackColor", false, colour);
}
}
Rangy is a cross-browser range and selection library that solves this problem perfectly with its CSS Class Applier module. I'm using it to implement highlighting across a range of desktop browsers and on iPad and it works perfectly.
Tim Down's answer is great but Rangy spares you from having to write and maintain all that feature detection code yourself.
Could you please elaborate the need of this functionality. If you only want to change the highlight style of the selected text you can use CSS: '::selection'
More Info: http://www.quirksmode.org/css/selection.html https://developer.mozilla.org/en/CSS/::selection
var userSelection = document.getSelection();
var range = userSelection.getRangeAt(0);
Instead of surroundContent method you can use the appendChild and extractContents methods this way:
let newNode = document.createElement('mark');
newNode.appendChild(range.extractContents());
range.insertNode(newNode);
function markNode() {
if(document.getSelection() && document.getSelection().toString().length){
let range = document.getSelection().getRangeAt(0);
let newNode = document.createElement('mark');
newNode.appendChild(range.extractContents());
range.insertNode(newNode);
}
else{
alert('please make selection of text to mark');
}
}
function resetContent() {
testMe.innerHTML = `Remember: <a href="https://developer.mozilla.org/en-US/docs/Web/API/Node">Read</a> and <strong>stay strong</strong>`;
}
<p id="testMe">Remember: <a href="https://developer.mozilla.org/en-US/docs/Web/API/Node">Read</a> and <strong>stay strong</strong></p>
<div><button onclick="markNode()">markNode</button></div>
<div><button onclick="resetContent()">resetContent</button></div>