Wrap one element with another while maintaining a wrapper link?

The jQuery wrap() method does not transfer the use of the element you created, but a duplicate:

 var $orig = $('p'); // some existing element var $wrap = $('<div>').css({border:'1px solid red'}); $orig.wrap($wrap); $wrap.append('<p>SMOKE YOU</p>'); // does not appear after the original element 

If you are not sure, you can see the live version above: http://jsfiddle.net/QRmY6/

What is the best way to create non-trivial dynamic content to wrap an existing node while maintaining a link to the wrapper that ends around the content?

+8
javascript jquery
source share
3 answers

The best alternatives I came up with are the following:

 // Technique 1 - swap it out and then embed it via append var $wrap = $('<div>').css({border:'1px solid red'}); $orig.replaceWith($wrap); $wrap.append($orig); // Technique 2 - create it inline and then modify it var $wrap = $orig.wrap('<div>').parent().css({border:'1px solid red'}); 
+4
source share

Although this has long been asked, it is still a problem (as of June 2015) in jQuery (v1.11.1). Here's my workaround that feels a little ... well, say, "special", but nonetheless works:

 var $orig = $('p'); // some existing element var $wrap = $('<div>').css({border:'1px solid red'}); $wrap = $orig.wrap($wrap).parent(); //the object that is being wrapped is returned, so selecting its parent will get the wrapper. Re-setting that in the $wrap variable will retain the wrapper for reference $wrap.append('<p>SMOKE YOU</p>'); // this will now work 

Note. The caveat is that the $wrap element can no longer be reused for packaging, as it now contains the $orig element. A workaround for this is to use add() another β€œspecial” way:

 var $orig = $('p'); // some existing element var $wrap = $('<div id="wrapper">').css({border:'1px solid red'}); $wrap = $wrap.add($orig.wrap($wrap.clone().empty()).parent()); //the object that is being wrapped is returned, so calling for its parent will return the wrapper. $wrap.append('<p>SMOKE YOU</p>'); // this will now work $wrap = $wrap.add( $('div.otherdiv').wrap($wrap.clone().empty()).parent()) console.log($wrap); //as you can see the $wrap variable now contains two divs $wrap.css({'border' : '1px solid blue'}); //this will now work on all wraps 

This is not very clean code, but it works! See this script for a working example.

+1
source share

Surprised that jQuery is not smart enough to keep the link. Here is an easy way to vanilla JS:

 orig.parentNode.replaceChild(wrapper,orig); wrapper.appendChild(orig); 
0
source share

All Articles