Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrap one element with another, retaining reference to wrapper?

The jQuery wrap() method does not wrap using 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 convinced, you can see a live version of the above here: http://jsfiddle.net/QRmY6/

How do I best create non-trivial dynamic content to wrap around an existing node while retaining a reference to the wrapper that ends up around the content?

like image 520
Phrogz Avatar asked Apr 18 '11 18:04

Phrogz


2 Answers

The best alternatives I have come up with are:

// 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'});
like image 53
Phrogz Avatar answered Nov 09 '22 18:11

Phrogz


Although this has been asked a long time ago, it is still an issue (as of june 2015) in jQuery (v1.11.1). Here's my workaround, which feels a bit.. well, shall we say 'special', but works nonetheless:

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 is no longer re-usable for wrapping, as it now contains the $orig element. Workaround for that is by using add() in 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

It's not very clear code, but it works! See this Fiddle for a working example.

like image 21
Klaas Leussink Avatar answered Nov 09 '22 16:11

Klaas Leussink