Reputation: 13
been struggling with this for a while now. Really hope someone can help me out.
Im trying to make divs which are removable when you click onto them. They have a css-class 'tag-show' which is added and removed (this works), so the selector seems to be fine i guess..?
Why is the $(this).remove() not working?
$(document).ready(function() {
// selectors
var module = $(".divCreate");
var list = module.find(".listTag");
var button = module.find(".divButton");
// the actual issue
button.click(function() {
list.append("<div class='tag'>Tag</div>");
setTimeout(function() {
list.find(".tag").last().addClass("tag-show").on("click", function() {
$(this).removeClass("tag-show");
setTimeout(function() {
$(this).remove();
},190);
});
},40);
})
});
Upvotes: 1
Views: 605
Reputation: 1326
I have made some improvments to your code, adding comments where it was needed. Just check the code below and its comments.
Your problem with remove is that the this
in your case is "triggering" the closest parent, which is setTimeout
, not clicked element.
For a better understanding just try to call console.log(this);
inside timeout function and click function, you will see the difference.
I have made an fiddle which can help you understand better (open developer tools to see the console result)
$(document).ready(function() {
// when you keep DOM elements in variables is better to put $ in the beginning
var $module = $(".divCreate");
// faster than .find()
var $list = $(".listTag", $module);
// can not call 'on' with variable
//var $button = $(".divButton", $module);
// called through document since we need to handle dynamic added elements - check event delegation
$(document).on("click", ".divButton", function() {
$list.append("<div class='tag'>Tag</div>");
setTimeout(function() {
// some improvments
$(".tag", $list).last().addClass("tag-show");
}, 40);
// Just keep this if you have divButton attached to an anchor element
// Useful for preventing default behvaiour - in this case adding "#" to url
return false;
});
// Do not need to create the event inside that event
$(document).on("click", ".tag-show", function() {
// Since we use an element more than once is better to
// add it into a variable to avoid performance issues - js caches it and call the variable
var $el = $(this); // our needed 'this'
$el.removeClass("tag-show");
setTimeout(function() {
// 'this' here returns some properties of window (where setTimeout belongs), we need to call element cached above
//(the 'this' above contains what we need)
$el.remove();
}, 190);
});
});
Note : still do not understand why you need these timeouts but it s up to you, maybe you need them with a bigger interval :D
Upvotes: 0
Reputation: 1213
You should use the jQuery .on()
function instead of .click()
, as it works for dynamically created elements. Then you also don't have to apply it to the element each time it is dynamically added.
Somewhere else in your code within $(document).ready(function() {});
add this event handler:
$('.listTag').on('click', 'div.tag', function() {
$(this).remove();
});
and it should work for any element that is matched by the div.tag
selector.
Upvotes: 1
Reputation: 6917
Not sure what you're trying to accomplish, but perhaps this is a better way to accomplish the same task?
// selectors
var module = $(".divCreate");
var list = module.find(".listTag");
var button = module.find(".divButton");
// the actual issue
button.click(function() {
list.append("<div class='tag'>Tag</div>");
})
$(document).on('click','.tag', function(){
$(this).remove();
});
https://jsfiddle.net/7daffjh8/
Upvotes: -1
Reputation: 169
"this" loses it's context in your setTimeout. add a var containing this and use that instead. like so
var self = $(this);
setTimeout(function() {
$(self).remove();
},190);
I think that would fix it.
Upvotes: 2
Reputation: 1266
this
inside the setTimeout
callback is not referring to the div
anymore. You could bind the callback to the div
or do something like this:
var $this = $(this);
setTimeout(function() {
$this.remove();
},190);
Upvotes: 0