skip to Main Content

I have this:

<p>
An 

<span class="item1">easyJet pilot</span> 

has told tourists that flying to

<span class="item2">Rhodes</span> 

is a “terrible idea” just minutes before taking off, it has 
been reported, as 

<span class="item3">wildfires spread across Greece</span> 

journalist Gwyn Loader, who was on the flight to the 
island to report for BBC Wales Welsh-language news programme 
Newyddion, said 

<span class="item4">eight passengers</span>

subsequently decided
to disembark, including a young boy who was in tears.

</p>

If I select a span or a part of a span, I would like to remove the span tagnames and append the selected text to the parentNode

For example, in , if I select "across", I would like it to be removed from the span and appended to the parentNodep. Therefore, it would create 2 spans as "wildfires spread" would be one and "Greece" would be a new one.

I am able to do it by using this:

const element = document.querySelector('span');
element.outerHTML = element.innerHTML

But this is removing the span elements one by one and not the one I could select using the mouse.

So I have tried to create a function:


function cleanup() {
            const selObj = window.getSelection();
            const selRange = selObj.getRangeAt(0);
            selRange.outerHTML = selRange.innerHTML
            
        }

But it is not working, although I have no error. The problem comes from the selection but I cannot figure out how to fix it.

What am I missing?

Thank you very much for your help,

2

Answers


  1. You need to add event listener for the span and then replace the content like below.

    document.querySelectorAll('span').forEach(sp => {
        sp.addEventListener('click', e => {
            e.target.outerHTML = e.target.innerHTML;
        });
    });
    
    Login or Signup to reply.
  2. The issue with your current approach is that you are trying to directly modify the outerHTML of the selected range, which is not supported. Instead, you should use the range object’s extractContents() method to get the selected content as a document fragment, remove the elements from that fragment, and then insert the modified fragment back into the document.

    <p>
      An <span class="item1">easyJet pilot</span> has told tourists that flying to
      <span class="item2">Rhodes</span> is a “terrible idea” just minutes before taking off, it has been reported, as
      <span class="item3">wildfires spread across Greece</span> journalist Gwyn Loader, who was on the flight to the
      island to report for BBC Wales Welsh-language news programme Newyddion, said
      <span class="item4">eight passengers</span> subsequently decided to disembark, including a young boy who was in tears.
    </p>
    
    <script>
      function cleanup() {
        const selObj = window.getSelection();
        const selRange = selObj.getRangeAt(0);
    
        // Create a new div element to hold the selected content
        const tempDiv = document.createElement('div');
        tempDiv.appendChild(selRange.cloneContents());
    
        // Remove span tags from the selected content
        const spanElements = tempDiv.querySelectorAll('span');
        spanElements.forEach(span => {
          const textNode = document.createTextNode(span.textContent);
          span.parentNode.replaceChild(textNode, span);
        });
    
        // Insert the modified content back into the document
        selRange.deleteContents();
        selRange.insertNode(tempDiv);
    
        // Clear the selection
        selObj.removeAllRanges();
      }
    
      // Example: Call the cleanup function when a span is clicked
      const spans = document.querySelectorAll('span');
      spans.forEach(span => {
        span.addEventListener('click', cleanup);
      });
    </script>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search