skip to Main Content

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


  1. 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).

    Login or Signup to reply.
  2. 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.

    document.getElementById("normal").addEventListener("click", function() {
      const selection = window.getSelection();
      if (selection.rangeCount > 0) {
        const range = selection.getRangeAt(0);
        const container = range.commonAncestorContainer;
        if (container.nodeType === 3) {
          const parentElement = container.parentNode;
          const wrapper = document.createElement("div");
          wrapper.appendChild(container.cloneNode(true));
          const text = wrapper.innerHTML;
          parentElement.innerHTML = parentElement.innerHTML.replace(container.textContent, text);
        } else {
          const spansToRemove = container.getElementsByTagName("span");
          const spansToRemoveArray = Array.from(spansToRemove);
    
          for (const span of spansToRemoveArray) {
            if (range.intersectsNode(span)) {
              const textNode = document.createTextNode(span.textContent);
              span.parentNode.replaceChild(textNode, span);
            }
          }
        }
      }
    });
    <div contentEditable class="inner_card" id="card_txt">
      <p id="text">
        Lorem ipsum dolor sit amet consectetur adipisicing elit.
        <span style="color:red;">Exercitationem magnam</span> magni pariatur suscipit... Vel exercitationem <span style="font-weight:bold;">deserunt reprehenderit</span> expedita temporibus esse...
      </p>
    </div>
    <button id="normal">Normalize text</button>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search