Search code examples
javascripthtmldominnerhtmlreplacewith

Formatting lost when using .replaceWith(textContent)


I'm trying to move a div "up" a level and get rid of a blockquote. As you can see in this fiddle, when you click "Change", the bold font is not preserved. I have also tried using innerHTML and innerText instead of textContent but neither worked. Here is the HTML:

<html>
    <div id="outerdiv">
    <blockquote><div id="innerdiv"><b>Hello </b>Text 1</div></blockquote>
    </div>
<span onclick="removeblockquotes(this)">Change</span>
</html>

And the JS:

function removeblockquotes(e)
{for (const b of document.querySelectorAll('blockquote')) {
  if (!b.closest('div')?.parentElement.closest('div')) {
    b.replaceWith(b.textContent);
  }
}
}

Solution

  • You can set the outerHTML of the container to the innerHTML container, thereby removing the container but preserving the markup inside:

    for (const b of document.querySelectorAll('blockquote')) {
      if (!b.closest('div')?.parentElement.closest('div')) {
        b.outerHTML = b.innerHTML;
      }
    }
    <html>
    <div id="outerdiv">
      <blockquote>
        <div id="innerdiv"><b>Hello </b>Text 1</div>
      </blockquote>
    </div>

    Another approach that'll preserve listeners, by iterating through the children and appending each:

    for (const b of document.querySelectorAll('blockquote')) {
      if (!b.closest('div')?.parentElement.closest('div')) {
        while (b.children.length) b.insertAdjacentElement('afterend', b.children[0]);
        b.remove();
      }
    }
    <html>
    <div id="outerdiv">
      <blockquote>
        <div id="innerdiv"><b>Hello </b>Text 1</div>
      </blockquote>
    </div>