I'm trying to write some code to let the user highlight parts of a website's content. To do so, I replace the user selection (selectedText
) by some HTML (<div class = "highlight">selectedText</div>
) - and it works (cf. code below).
The problem is that wrapping the selected text in this way overrides the rest of the CSS and ruins the layout, regardless of the HTML tag used as a container (div, span, em, mark, hr, ...). I apologize if the solution to this problem is obvious, I'm quite new to web dev.
JS
document.addEventListener("mouseup", function() {
var selectedText = getSelectedText();
if (selectedText.length > 0) {
div = document.createElement("div");
div.innerHTML = selectedText.trim();
div.classList.add("highlight");
replaceSelection(div);
}
});
CSS
div.highlight {
background-color: #F5E283;
display: inline;
}
// Highlighter
// Selection: thx http://www.javascriptkit.com/javatutors/copytoclipboard.shtml :)
function getSelectedText() {
var selection = "";
if (window.getSelection) {
var selection = window.getSelection().toString();
}
return selection
};
// Replacement: thx https://stackoverflow.com/questions/3362747/how-to-insert-an-element-at-selected-position-in-html-document/3363087#3363087
function replaceSelection(replacement) {
var range, html;
if (window.getSelection && window.getSelection().getRangeAt) {
range = window.getSelection().getRangeAt(0);
range.deleteContents();
range.insertNode(replacement);
} else if (document.selection && document.selection.createRange) {
range = document.selection.createRange();
html = (replacement.nodeType == 3) ? replacement.data : replacement.outerHTML;
range.pasteHTML(html);
}
}
document.addEventListener("mouseup", function() {
var selectedText = getSelectedText();
if (selectedText.length > 0) {
console.log(selectedText);
mark = document.createElement("mark");
mark.innerHTML = selectedText.trim();
mark.classList.add("highlight");
replaceSelection(mark);
}
});
div.highlight {
background-color: yellow;
}
<! DOCTYPE HTML>
<html>
<body>
<h1>Please, select this h1</h1>
<p>and this text at the same time</p>
<h1>Now, select <i>a part of this one</i></h1>
<p>with this text</p>
<p></p>
</body>
</html>
and
in the example. you need to find a way to go through each element inside the selection and create the highlight inside all of them. It's not trivial, I've been trying to play a bit with it as it's an interesting challenge but with limited success so far. if you want to take a look at what I've tried and try to improve on it - https://jsfiddle.net/FabioSG/59gsdfcx/5/
– FabioG May 01 '20 at 18:16