user1888521
user1888521

Reputation: 135

jQuery: .on ('click', [selector]) only works when delegated

I'm pretty new with jQuery. I have li's being created and appended to a ul. Inside that li I have a div containing a button that when clicked will remove that li from the ul. Basically:

<ul class="imageList">
  <li>Image</li>
  <li>Image1<div class="deleteImg"></div></li>
</ul>

My .on('click') works when I delegate the event like so:

$('.imageList').on('click','.deleteImg', function() {
        $(this).parent().remove();
    });

But not if I fire it right off the div:

$('.deleteImg').on('click', function() {
        $(this).parent().remove();
    });

Could someone please explain why? I read the jQuery API but it's still somewhat confusing to me. I realize that delegating the event is more efficient, but shouldn't both work?

Upvotes: 3

Views: 124

Answers (4)

Faust
Faust

Reputation: 15404

This will be the case If .deleteImg doesn't exist on page-load but .imageList does.

The click event bubbles up through all the ancestor elements of .deleteImg, and so you can assign a listener for that event on one of ancestors that exists at page-load, .imageList1 in this case. When the descendent .deleteImg is clicked, the listener attached to the ancestor detects the event, and runs the anonymous function you specified with .on().

Upvotes: 0

James Montagne
James Montagne

Reputation: 78690

When you do anything like this:

$(SOME_SELECTOR).on(...

A handler is attached to all elements matching the selector at that time. Any elements created later do not automatically get the handler attached.

Upvotes: 0

Adil Shaikh
Adil Shaikh

Reputation: 44740

Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time.

http://api.jquery.com/on/

As you are adding your element dynamically - you need to delegate event's like this -

$('.imageList').on('click','.deleteImg', function() {
        $(this).parent().remove();
});

While this just attach event to the element's which are present in DOM at the time you are executing this -

$('.deleteImg').on('click', function() {
        $(this).parent().remove();
});

Upvotes: 1

Travis J
Travis J

Reputation: 82297

"I have li's being created and appended to a ul."

The reason this will only work with delegation is because the element technically exists after event registration would be done. As a result of that, you would need to delegate the event out in order to have it be attached to all new instances of the selector given.

Another route people take is directly attaching the events when the element is dynamically created before appending.

For example:

var $d = $("<div>Hello</div>");
$d.click(function(){ alert("Hello"); });

Upvotes: 1

Related Questions