Reputation: 46
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>
Upvotes: 2
Views: 739
Reputation: 438
I think I understand the issue. If you have styling on the h1 element, highlighting the text will remove the h1 styling as the highlighted element becomes a child of h1. Try this if you, for example, want to change the color:
h1, h1 div.highlight{
color: red;
}
or
h1{
color: red;
}
div.highlight{
color: inherit;
background-color: #F5E283;
display: inline;
}
I also noticed an issue with the trim - if I select 'this ' in the string 'select this h1', the trailing space is trimmed and you get 'select thish1', which i prop not what you want.
Will it work without selectedText.trim()?
Cool feature so it gets fully working!
Upvotes: 1