rgm
rgm

Reputation: 13

jQuery - Make dynamically created DIV remove itself on click

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

Answers (5)

stefanz
stefanz

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

amklose
amklose

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

stackoverfloweth
stackoverfloweth

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

DRGA
DRGA

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

orlland
orlland

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

Related Questions