Reputation: 2610
I'm trying to wrap some HTML content inside a div container and then append a span to that container. But I can't figure out why the appended span doesn't appear.
So I'm curious if I'm doing something wrong.
$('button').click(function() {
var $container = $('<div class="container"></div>');
$('.target').wrap($container);
$label = $('<span class="duration-label">Hi there</span>');
$label.appendTo($container);
});
.target {
border: 1px solid black;
}
.container {
background: red;
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div class="target">
<span>This is some unimportant text</span>
</div>
<button type="button">Click me</button>
Upvotes: 3
Views: 52
Reputation: 46361
The reason is that the .wrap()
method wraps each element in the set of matched elements with a new element structure - copies of $container
.
$container
itself is not the wrapping element, it's just a "template" for wrapping elements, so you need to grab the actual element(s) if you want to further manipulate them.
This of course is simple to understand once you consider the fact that after the call there can be more then 1 such element.
$('button').click(function() {
var $container = $('<div class="container"></div>');
var $wrappingContainer = $('.target').wrap($container).parent();
// sanity check:
if($container[0] == $wrappingContainer[0]) {
alert('Same object?!?!'); // Should not happen
}
$label = $('<span class="duration-label">Hi there</span>');
$label.appendTo($wrappingContainer);
});
.target {
border: 1px solid black;
}
.container {
background: red;
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div class="target">
<span>This is some unimportant text</span>
</div>
<button type="button">Click me</button>
Upvotes: 1
Reputation: 1075825
It's because wrap
makes a copy of the wrapper you give it, it doesn't use the one you give it directly. You're appending to the one you gave it.
Instead, use the one you wrapped around the content:
$('button').click(function() {
// Wrap .target with the div, and get a reference to
// the newly-created wrapper
var $container =
$('.target')
.wrap('<div class="container"></div>')
.parent();
// Add a label to it
var $label = $('<span class="duration-label">Hi there</span>');
$label.appendTo($container);
});
.target {
border: 1px solid black;
}
.container {
background: red;
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div class="target">
<span>This is some unimportant text</span>
</div>
<button type="button">Click me</button>
Side note: Your code was falling prey to The Horror of Implicit Globals because you didn't declare $label
. It's important to declare your variables. You can use strict mode to have the JavaScript engine keep you from creating globals implicitly.
Upvotes: 2
Reputation: 82241
That is because $container
refers to variable and not object of wrapped element. You need to get the object or use relevant selector to append to container element :
$label.appendTo('.container');
Upvotes: 1