Reputation: 41
I've been working on how to allow visitors to select multiple sections of text wrapped in <p>
tags to highlight them, and then click a button to remove all highlights.
classList
to created <span>
elements.Uncaught DOMException: Failed to execute 'surroundContents' on 'Range': The Range has partially selected a non-Text node.
classList
produces fragmented text with empty spans.I have tried to remove the child elements from the parent, but that removes the original text as well as the tag element. I think the DOMException is because of the created span tag, but I'm not sure how to remove them when a new selection overlaps.
I have looked at many SO articles, but they seem to focus on JQuery, which I am not using. There is still a lot I do not understand about JavaScript, so MDN has helped a bit, but I sometimes struggle to apply the concepts.
// HIGHLIGHT SELECTIONS
const elementToHighlight = document.getElementById('higlight-this');
elementToHighlight.addEventListener('mouseup', selection);
function selection() {
let element = document.createElement('span');
element.classList.add('hl');
window.getSelection().getRangeAt(0).surroundContents(element);
}
// REMOVE hl CLASS
const removeClassListFromAll = document.getElementById('remove');
removeClassListFromAll.addEventListener('click', () => {
let grabHighlighted = document.getElementsByClassName('hl');
while (grabHighlighted.length) {
grabHighlighted[0].classList.remove('hl');
// grabHighlighted[0].parentElement.removeChild.(grabHighlighted[0]);
}
});
.hl {
background-color: yellow;
}
<section id="higlight-this">
<p>Some text to test with. Make it look good with highlights!.<br>
If you don't, It won't be useful for you.</p>
</section>
<button id="remove">remove</button>
Upvotes: 4
Views: 1122
Reputation: 510
the main problem is your selection container is not right try to identify your selection using console.log() and add if else or switch like :
if(window.getSelection().getRangeAt(0).commonAncestorContainer.nodeName == "P")
window.getSelection().getRangeAt(0).surroundContents(element);
else { //this case when i select from top to bottom with the button
window.getSelection().getRangeAt(0).commonAncestorContainer.querySelector("#higlight-this").querySelector("p").getRangeAt(0).surroundContents(element);
}
Upvotes: 0