I try code in order users to be able to remove spans from a selection of a contentEditable .
The code works, but removes all spans from entire body and not only from the selection, as I want.
Here is the code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div contentEditable class="inner_card" id="card_txt">
<p id="text">
Lorem ipsum dolor sit amet consectetur adipisicing elit.
<span style="color:red;"><span style="font-weight:bold;">Exercitationem magnam</span> magni pariatur suscipit?</span> Assumenda molestias harum,
esse eligendi dolores eius nemo deserunt placeat dolorem necessitatibus exercitationem,
quaerat quo, qui iste dignissimos neque amet aut aperiam.
Vel exercitationem <span style="font-weight:bold;">deserunt reprehenderit</span> expedita temporibus esse,
et totam consequatur provident recusandae optio facilis, ipsam culpa, deleniti tenetur!
Fuga ab consequuntur natus omnis cum in eos praesentium animi corporis accusamus quas labore
nobis tenetur doloribus totam alias, <span style="font-style:italic; font-weight:bold;">vitae eius repellendus voluptates,</span> quod autem magnam necessitatibus.
Quia temporibus quibusdam suscipit, incidunt officia ea perferendis laborum adipisci,
consequatur <span style="text-decoration:underline 2px green;">veniam, sequi ipsum accusantium vel odit nobis esse minus.</span>
</p>
<button id="normal">Normalize text</button>
</div>
<script>
function recover() {
for (i = 0; i < document.getElementsByTagName('span').length; i++) {
var span = document.getElementsByTagName('span')[0];
var pa = span.parentNode;
while (span.firstChild) pa.insertBefore(span.firstChild, span);
pa.removeChild(span);
i--;
}
}
document.getElementById("normal").onclick = function() {
const selec = document.getSelection();
recover(selec);
}
</script>
</body>
</html>
2
Answers
Selections in JavaScript are kind of a nightmare.
You could use @timdown ‘s "rangy" library to apply a fake style and span over the selection content. This will remove existing spans. And if you use this with a MutationObserver (Is there a JavaScript / jQuery DOM change listener?) you can detect the new span(s) that have been added, and then delete them too (make sure to preserve the span’s text nodes).
Here, we first check if the
container
of the user selection is a text or element node in the DOM tree.If it is a text node, the parent element’s innerHTML is replaced with the text to remove the span.
Otherwise (if it is a container node), we create a new text node for each span and replace them with that text.