I am using a mouseup event to trigger a function which highlights text and surrounds the highlighted text with a span (function from stack overflow):
function highlightText(e) {
var t = window.getSelection().toString();
if (t) {
$("#mySpan").remove();
var range = window.getSelection().getRangeAt(0);
newNode = document.createElement("span");
newNode.id = 'mySpan';
range.surroundContents(newNode);
}
}
The main problem I am encountering is that as long as surroundContents
is included, the text remains highlighted only about 20% of the highlight attempts (otherwise highlighting disappears immediately). I tried adding a setTimeout, not calling surroundContent for 1s. I also tried removing the remove() statement, but still no good.
Any ideas on why this is happening?
I was facing the same problem with Chromium on Android. In some specific cases, the call of range.surroundContents(newNode)
would cause a very weird behaviour of page reload and so on. After checking the documentation of the function:
This method is nearly equivalent to newNode.appendChild(range.extractContents()); range.insertNode(newNode). After surrounding, the boundary points of the range include newNode.
So the obvious thing was to apply another way highlight the text. I found mark.js library which did exactly what I wanted without that annoying side effect. (Here's a JSFiddle sample that shows how it's used to highlight just selection). The difference is that library was not using range.surroundContents(newNode)
nor newNode.appendChild
but rather node.replaceChild
.
Based on that, here's the solution to the problem I was having and I think it applies to your case as well.
function surroundRangeWithSpan(range) {
var span = document.createElement('span');
// The text is within the same node (no other html elements inside of it)
if (range.startContainer.isEqualNode(range.endContainer) && range.startContainer.childNodes.length == 0) {
// Here you customise your <span> element
customSurroundContents(range, span);
} else {
// Here you have to break the selection down
}
return span;
}
function customSurroundContents(range, span) {
var node = range.commonAncestorContainer;
var startNode = node.splitText(range.startOffset);
var ret = startNode.splitText(range.toString().length);
span.textContent = startNode.textContent;
startNode.parentNode.replaceChild(span, startNode);
}
And you pass window.getSelection().getRangeAt(0)
to the function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With