Xarth
Xarth

Reputation: 41

Javascript - Create elements using 'surroundContents' breaks when new selection overlaps previously selected text

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.

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

Answers (1)

Tarek Adra
Tarek Adra

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

Related Questions