Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery .on() method doesn't see new elements

I'm getting a JSON element and building a list from its items like this:

getTitles: function(data) {
    data = data || {};
    var list = [];

    $.getJSON(
        '/titles',
        data,
        function(data) {
            $.each(data.data, function(key, val) {
                list.push(
                    '<li><a href="'+ val.href +'">'+ val.title +'</a><span class="count">'+ val.count +'</span></li>'
                )
            });

            $('#title-items').html(list.join(''));
        }
    );
}

And I'm binding click event for a elements like this:

$('a').on('click', function(e) {
    alert('clicked');
    e.preventDefault();
});

Old a elements shows alert but new ones follow URL. Event handler doesn't work for new ones. How can I solve this?

like image 802
cnkt Avatar asked Dec 27 '11 23:12

cnkt


2 Answers

You are not using the correct code to get live functionality.

$('#title-items').on('click', 'a', function(e) {
    alert('clicked');
    e.preventDefault();
});
  1. First, select your common ancestor element (#title-items in this example). You can use document here too if you want to handle all a elements.
  2. Pass the event type (on), then the sub selector (a), and then the callback function for the event.

Now, when click events bubble up to #title-items, it will check to see if the element is an a element, and if so, fire the callback.

like image 108
alex Avatar answered Oct 17 '22 22:10

alex


You want to use event delegation to capture events triggered on events that are present in the DOM at any point in time:

$(<root element>).on('click', 'a', function(e) {
    alert('clicked');
    e.preventDefault();
});

UPDATE - In this example the <root element> is an ancestor of the links to which you are binding that is present in the DOM at the time of binding.

The basic idea is that since we can't attach an event handler to a DOM element not yet in the DOM, we attach the event handler to an ancestor element and wait for the event to bubble up to the ancestor element. Once the event reaches the ancestor event the event.target property is checked to see what was the originally clicked element.

like image 30
Jasper Avatar answered Oct 17 '22 21:10

Jasper