.on() event handler inside ajaxComplete()?

I have this:

$('.task').on('click', function()
{
    task_id = $(this).data('id');
    console.log('Task id: ' + task_id);
});

But this doesn't work as it should when the content is reloaded via ajax. task_id value stays the same even after clicking different elements after the ajax reload. Apparently I have to bind it to the body first.

This is how it is in my code right now though (it works as expected):

$(document).ajaxComplete(function(event, xhr, settings) {
    $('.task').on('click', function()
    {
        task_id = $(this).data('id');
        console.log('Task id: ' + task_id);
    });
});

But I've been told this duplicates/doubles the trigger for the .on('click') event? Is this true? How do I know then when to bind to the direct selector or bind to the document.body instead? Which would be more efficient? Binding to body or putting the event delegation inside ajaxComplete()?

I'm a little confused too since I have other event handlers inside the same .js file but outside ajaxComplete() that seem to work just fine even after an ajax reload?

Answers 1

  • You should use .on() method with Event Delegation approach, when generating elements dynamically(content is updated via $.ajax())/manipulating selectors. then you won't need to attach event handler in ajaxComplete()

    General Syntax

    $(document).on('event','selector',callback_function)
    

    Example

    $(document).on('click', '.task', function(){
        //Rest of your code
    });
    

    In place of document you should use closest static container.

    The delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, we can use delegated events to bind the click event to dynamically created elements and also to avoid the need to frequently attach and remove event handlers.


Related Articles