Reputation: 9466
I have a body on click function that conditionally adds or removes a button.
The adding works, but neither remove()
nor detach()
works.
I am rotating an image and I only want to show a "Save" button when the image is rotated from the original.
This is all inside document ready
$(document).ready(function() {
var $save = $('<div id="savebutton_container"><button name="savebutton" id="savebutton">Save</button></div>');
$('body').on('click','img',function() {
if(typeof rotate.counter == 'undefined') {
rotate.counter = 0;
}
rotate.counter += 90;
if(rotate.counter === 360) {
rotate.counter = 0;
}
console.log(rotate.counter);
$(this).removeClass(function(index,css){ // clear classes first.
return (css.match (/(^|\s)rotate\S+/g) || []).join(' '); // remove rotational classes
});
if(!(rotate.counter == 0) ) { // NOT 0 degrees
console.log('rotate counter is not 0');
$(this).addClass('rotate' + rotate.counter); // rotate the image
if( $("#savebutton_container").length === 0 ) { // WORKS!
$(this).parents().append($save); // global $save
}
} else {
console.log('rotate counter is 0');
$("#savebutton_container").detach(); // works seemingly randomly
// Also tried $save.detach();// also tried .remove();
}
});
});
Every once in a while the save button will disappear. The console ALWAYS logs the "rotate counter is 0" whenever it is supposed to, but the save button does not go away!
Upvotes: 1
Views: 1521
Reputation: 10305
I would suggest trying to use $(document).on('click'...)
instead of $(body).on()
Since the element that you have created is dynamically created you need to recheck the dom starting from the root of the dom tree.
Whenever I am using dynamic elements I always make sure that my event triggers are running off of my $(document)
selector.
Upvotes: 0
Reputation: 15240
I think the problem comes from your usage of parents()
instead of parent()
in the line
$(this).parents().append($save);
The parents()
method returns all ancestor elements from the selection, traversing up, while parent()
returns only the first parent.
You are retrieving all parents()
of the image (e.g. <body>
, <html>
, etc.) and appending $save
to all of them. Using append(elem)
on a multi-element selection results elem
being cloned and appended to every target in the selection. This is not what you want, and this is causing you to lose the $save
reference (especially since you are appending multiple copies of an element with the same id
).
This Plunkr has a slightly simplified working version of what you want (click on the image to test). Note that detach()
is correct, remove()
is not. detach()
preserves all jQuery metadata about the element, it is specifically used when you plan to re-attach the element later. remove()
is used when you want to discard the element.
Upvotes: 1