Skip to content

Instantly share code, notes, and snippets.

@mgroves
Created November 19, 2012 21:30
Show Gist options
  • Select an option

  • Save mgroves/4114106 to your computer and use it in GitHub Desktop.

Select an option

Save mgroves/4114106 to your computer and use it in GitHub Desktop.
// when I click the element after the page loads
// nothing happens: no error, no alert, nothing.
// when I run this same code in the JavaScript console
// THEN it will show the alert
// $("#" + context.reportId + " .some-css-class").length is 7
// in normal execution and in the console
// what the heck am I doing wrong
$("#" + context.reportId + " .some-css-class").click(function () {
alert("sorting!");
});
@brightstreetgroup
Copy link
Copy Markdown

$("#" + context.reportId + " .some-css-class").on("click",function () {
alert("sorting!");
});

@BruceHubbard
Copy link
Copy Markdown

Is the element your adding the click to present when the page loads/when that line executes? Or is it added later via AJAX/etc?

@BruceHubbard
Copy link
Copy Markdown

If it's added later then you'll need to do something like this:

$("#some_parent_thats_always_on_the_page").on('click', '.some-css-class', function() { alert("Sorting"); });

@mgroves
Copy link
Copy Markdown
Author

mgroves commented Nov 19, 2012

Yes, it's added in the 'success' event of an ajax call. That last snippet worked, so time for me to hit the jQuery docs some more I guess...

@BruceHubbard
Copy link
Copy Markdown

When your original line runs the element isn't on the page so it doesn't bind to anything. You could put your original line in your ajax success method after you've placed the element on the page and it should work. Something like this:

$.ajax({
..params omitted for brevity...
success: function(data) {
//put element on page
//run your original click binding function
}

The line I wrote works because of how events propagate. When you click on an element the browser checks the element for a click handler. If it doesn't find one it then checks the parent element for an click handler. If it finds one it executes it if not it checks it's parent and so on and so forth all the way up the chain until something handles the click or it runs out of parents.

So my line adds a click handler to a parent element that is on the page when the line executes (so it gets properly bound) and then the extra selector tells it what it was supposed to be bound to (what child element). So when you click the event gets propagated to the parent with the click event which will fire and look at what child element was clicked on and if it was the subselect you specified then it'll call your function. It's basically the equivalent of this (pseudo code):

$("#parent_div_on_the_page").click(function() {
if(/*click happened on my child with ".some-css-class" selector */) {
execute code
} else {
skip and continue to propagate
}
});

So the actual click handler is on the parent which is always on the page and you can replace the child elements all you want and the click handler will still work so it's perfect for dynamically created content. So knowing events propagate you could do this:

$('body').on('click', '.some-css-class', function() ......)

and it would also work but it wouldn't be as performant since the event would have to propagate several layers to get back to the body tag (but modern browsers have some optimization under the covers to help with that).

Anyway hope that helps I'm sure there are some official docs out there that would explain it better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment