Brett
Brett

Reputation: 20049

Binding a click event to content loaded via AJAX without making it delegated?

I have a situation where I am using the data attribute named data-command in many instances throughout a specific section of a site and instead of binding tons of separate click events I decided to just use the one and use a switch such as:

$('[data-command]').on('click', function(event) {

    // Prevent default click action
    event.preventDefault();

    // Get command
    var command = $(event.target).data('command');

    switch (command) {
        // Do stuff...
    }

    // Prevent default click action (IE 8)
    return false;

});

However it has just become an issue when trying to get it to work on data loaded via AJAX.

This obviously works..

$('#existing_element').on('click', '[data-command]', function(event) {

...but since it is supposed to work on many different pages in that section of the site the above wouldn't work on all pages.

I could just make sure to give a specific id to the parent wrapper where I load all my ajax data, but that would mean making two separate binding events with a bunch of the same code.

I also could do this to cover all bases..

$(document).on('click', '[data-command]', function(event) {

...but that's probably not such a wise idea binding an element to the document.

Edit: Html data is being loaded into the DOM via jQuery's html method.

Any clean way I can handle this or should I just create two different binding events to handle each situation?

Upvotes: 4

Views: 244

Answers (1)

Tushar
Tushar

Reputation: 87203

Event delegation is the best approach to bind events on dynamically created elements. Since you don't want to use event delegation, use following approach to bind events.

$('[data-command]').off('click').on('click', clickHandler);

// Somewhere in the same scope
function clickHandler(e) {
    // Handle click event here
}

Add this after the dynamically created elements are added using html().

off('click') will first unbind the click event handlers that are applied previously and then on('click', will bind the click handler on all the elements matching selector.


Edit

This seems to be repeating the same code again and again. Can't I keep it DRY?

Yes, you can keep the code DRY and clean by creating a function to bind events and call the same function when you want to bind event.

function clickHandler(e) {
    // Handle click event here
}

function bindEvent() {
    $('[data-command]').off('click').on('click', clickHandler);
}

$(document).ready(bindEvent);

...

$.ajax({
    ...
    success: bindEvent
....

Upvotes: 2

Related Questions