$(div).click(function) on $.ajax generated HTML

I'm making a shop catalogue and the products HTML are generated through $.AJAX request on the $(document).ready(function().

  $.ajax({
  url: "../includes/geracatalogo.php",
  method: "post",
  data: {tipos: tipos, categorias: categorias, pagina: pagina},
  success: function(html){
     $("#produtos").empty();
     $("#produtos").fadeOut(0);
     $("#produtos").append(html);
     $("#produtos").fadeIn(700);
       }
});
}); 

Now, on this HTML, I have the page number (all pages and selected one).I want to add a .clickEvent on this page button.

$(".pages").click(function(){
$(this).toggleClass('selected');
});

My doubt is, where I put the snippet above? On success function? Or outside $.Ajax?

The problem is: If I put it on $(document).ready(function(), the Event Listener will be created before the DIV (fail to hook).

Any ideas?

Upvotes: 0

Views: 765

Answers (2)

Claudio Redi
Claudio Redi

Reputation: 68400

Define it outside the success function. You could use event delegation for hooking events handlers to elements that doesn't exist yet.

$(document).on('click', '.pages', function(){
    $(this).toggleClass('selected');
});

document can be replaced but any existing container of .pages. See on documentation for more details, in particular, pay attention to section Direct and delegated events.

Upvotes: 2

David
David

Reputation: 218847

You can use jQuery's .on() function to solve this. So it might look something like this:

$(document).ready(function () {
    $(document).on('click', '.pages', function () {
        $(this).toggleClass('selected');
    });
});

(I'm not sure if it even needs to do in $(document).ready() but if all the other event binders are there then you might as well keep them together.)

What this essentially does is, instead of binding to the click event of the element itself, it binds to the click event of the document (the selector on which .on() is called, which can be any parent element above the target elements). When the click takes place, that event bubbles up through the DOM. So in this case, the click event gets up to document which then uses this handler.

The second argument is the selector to filter click events. So while this handler technically receives all click events which bubble up the DOM, it's going to ignore any that don't match the selector. (In this case, .pages.) Finally, there's the function used in response to the event.

Since this binds only once to an overarching parent element, it doesn't need to re-bind as child elements are added. Those elements can be added and removed all you want, the click event in question is happening above them. Also, since it binds only once, there's a performance improvement over binding the same handler to many child elements.

Upvotes: 0

Related Questions