How can I remove wrapper (parent element) without removing the child?

24,179

Solution 1

Could use this API: http://api.jquery.com/unwrap/

Demo http://jsfiddle.net/7GrbM/

.unwrap

Code will look something on these lines:

Sample Code

$('.button').click(function(){
    $('.wrapper img').unwrap();
});

Solution 2

Pure JS (ES2015) solution, in my opinion easier to read than jQuery-solutions.

node.replaceWith(...node.childNodes)

Node has to be an ElementNode

const wrapperNode = document.querySelector('h1')
wrapperNode.replaceWith(...wrapperNode.childNodes)
<h1>
  <a>1</a>
  <b>2</b>
  <em>3</em>
</h1>

Solution 3

Pure JS solution that doesn't use innerHTML:

function unwrap(wrapper) {
    // place childNodes in document fragment
    var docFrag = document.createDocumentFragment();
    while (wrapper.firstChild) {
        var child = wrapper.removeChild(wrapper.firstChild);
        docFrag.appendChild(child);
    }

    // replace wrapper with document fragment
    wrapper.parentNode.replaceChild(docFrag, wrapper);
}

Try it:

unwrap(document.querySelector('.wrapper'));

Solution 4

Surprised that nobody's posting the simplest answer:

// Find your wrapper HTMLElement
var wrapper = document.querySelector('.wrapper');

// Replace the whole wrapper with its own contents
wrapper.outerHTML = wrapper.innerHTML;

Solution 5

Pure javascript solution, i'm sure someone can simplify it more but this is an alternative for pure javascript guys.

HTML

<div class="button" onclick="unwrap(this)">Remove wrapper</div>

Javascript (pure)

function unwrap(i) {
    var wrapper = i.parentNode.getElementsByClassName('wrapper')[0];
    // return if wrapper already been unwrapped
    if (typeof wrapper === 'undefined') return false;
    // remmove the wrapper from img
    i.parentNode.innerHTML = wrapper.innerHTML + i.outerHTML;
    return true;
}

JSFIDDLE

Share:
24,179

Related videos on Youtube

lipenco
Author by

lipenco

Updated on September 19, 2021

Comments

  • lipenco
    lipenco over 2 years

    I would like to remove the parent without removing the child - is this possible?

    HTML structure:

    <div class="wrapper">
      <img src"">
    </div>
    <div class="button">Remove wrapper</div>
    

    After clicking on the button I would like to have:

    <img src"">
    <div class="button">Remove wrapper</div>
    
    • Joe Simmons
      Joe Simmons over 10 years
      You may lose the event listeners attached to the children, but yes, you can do that.
  • Kai
    Kai over 10 years
    should it be $('.wrapper img').unwrap() ?
  • Tushar Gupta - curioustushar
    Tushar Gupta - curioustushar over 10 years
    check you working fiddle some problem after unwrapping. Fix it .
  • PSL
    PSL over 10 years
    +1 and if there are more contents then $('.wrapper').children().unwrap();
  • Tats_innit
    Tats_innit over 10 years
    Merci Yo! :) your +1 is gracefully accepted, cheers for more stuff for OP.
  • dude
    dude almost 8 years
    Using innerHTML is evil, it will delete all your events inside the HTML.
  • Jay Harris
    Jay Harris almost 8 years
    @julmot clearly... (: if you want a solution that does that, scroll up or down and you'll find it. I'm not here to create duplicate answers especially when the question didn't ask to keep the event handlers. (;
  • ajbeaven
    ajbeaven over 7 years
    why is avoiding innerHTML preferable?
  • HeyHeyJC
    HeyHeyJC over 7 years
    @ajbeaven Keeping the existing DOM objects (rather than recreating them using innerHTML) means any event listeners attached to them are maintained.
  • bormat
    bormat over 7 years
    interesting even if you loose listener
  • Robbendebiene
    Robbendebiene over 5 years
    Nice solution, but there is no need to remove the children from the wrapper since docFrag.appendChild(wrapper.firstChild); will automatically move a node from its current position to its new position. Read more about appendChild on MDN
  • Andrew Cheong
    Andrew Cheong over 4 years
    +1 and if (sometimes) there's only text content (i.e. no child elements), then $('.wrapper').contents().unwrap();
  • Shnigi
    Shnigi over 2 years
    With typescript: const unwrap = (node: Element) => { node.replaceWith(...Array.from(node.children)); };
  • di3
    di3 about 2 years
    Keeps child event listeners and simple solution.