Reputation: 227310
I have a <div>
; it contains a <span>
. When you click on the <div>
, it removes the span, and replaces it with a <div>
containing an <input>
and a <button>
. This is all well and good.
The <button>
, when clicked is supposed to remove its parent <div>
(the appended one) and replace it with a <span>
again, but something is wrong. It seems that the parent <div>
isn't a part of the DOM!
Anyway, here's a quick example:
<div id="myPage">
<div id="clickMe" class="selectedField editMe">
<span>Click Me</span>
</div>
</div>
Some HTML, nothing too fancy. Though, since the DOM is gonna keep changing, I used .on
to delegate the events. Here's the JavaScript:
$(function(){
$('#myPage').on('click', '.selectedField', function () {
if($(this).hasClass('editMe')){
var $this = $(this).toggleClass('editMe editing'),
$input = $('<input/>', {
placeholder: 'type something...'
}),
$cancel = $('<button></button>', {
class: 'cancel',
type: 'button',
html: 'x'
})
$this.children('span').replaceWith($('<div></div>').append($input, $cancel));
}
});
$('#myPage').on('click', '.selectedField .cancel', function () {
var $this = $(this).closest('.selectedField').toggleClass('editMe editing');
console.log($this.children('div')[0]);
$this.children('div').replaceWith('<span>Click Me</span>');
});
});
DEMO: http://jsfiddle.net/Z8abW/
This looks simple enough, right? Clicking the box replaces the <span>
with a <div>
, then clicking the (newly added) <button>
puts the <span>
back.
But, this doesn't work. The first event works. I can click to add the <input>
and the <button>
, but clicking the <button>
does not work.
I don't know how to explain it, but it seems the <div>
I want to remove isn't part of the DOM! When I click on the <button>
, nothing happens on the page. I added a console.log
to make sure the event was being ran. Sure enough, it was, but something was odd.
I'm using Chrome 27, and its console has a neat feature. If you console.log
DOM elements, you can hover over them in the log and it will highlight them in the page. I did console.log($this[0])
, and it highlighted the element, like I would expect. But, when I did console.log($this.children('div')[0]);
, the element was not highlighted in the page! Why not? Makes me think the element, for some reason, isn't in the DOM. It does log a <div>
to the console, but it doesn't seem to be the one in the actual DOM.
Because of this the $this.children('div').replaceWith
line doesn't do anything!
What's going on! Why can I replace the <span>
with a <div>
, but not the other way around?
Upvotes: 9
Views: 156
Reputation: 208032
Propagation issues. Change:
$('#myPage').on('click', '.selectedField .cancel', function () {
to
$('#myPage').on('click', '.selectedField .cancel', function (e) {
e.stopPropagation();
The click on the cancel bubbles up and triggers the click event on the parent. Kill it with fire.
Upvotes: 9