2
$(document).ready(function() {
    $("img.tile").click(function() {
    var actid = $(this).data().id;
    $("#lz").load("/dialog/pre?actid=" + actid);
    $("#btnCheck").click(function() {
        alert("test");
    });
});

The load() call brings in an HTML fragment that has an <input id="btnCheck" value="Check" /> But the event doesn't fire when I click on it. Must have something to do with how the fragment is loaded. How do you make this work?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
BuddyJoe
  • 69,735
  • 114
  • 291
  • 466
  • If .load() is async, you should add the click handler in the callback for .load(). And according to the documentation, it looks like it is. :) – bzlm Jun 21 '11 at 17:50

3 Answers3

6

Correct, you either need to attached the click event after you are sure the data has loaded or use the live event to attach it. live will attach a handler if it finds it now or at any point in the future and is probably easiest to implement:

$("#btnCheck").live('click', function() {
    alert("test");
});

Alternatively, you can attach it after you are sure the data has loaded. As @bzlm pointed out in his comment load is an asynchronous event so you can't assume it has finished in any subsequent code. Fortunately load allows you to pass a function as a second argument that will fire after all of the data has loaded:

$("#lz").load("/dialog/pre?actid=" + actid, function() {
    $("#btnCheck").click(function() {
        alert("test");
    });
});
Chris Van Opstal
  • 36,423
  • 9
  • 73
  • 90
  • 3
    *"live will attach a handler if it finds it now or at any point in the future"* That's not how `.live()` works. It attaches the handler immediately when called, but it is attached to the `document`. *Every click on the page* that bubbles up to the `document` is tested against the `"#btnCheck"` selector, and if there's a match, it invokes the handler. The `.delegate()` method does the same, but is more localized, therefore preferred (by me anyway). :o) – user113716 Jun 21 '11 at 18:31
5

The best way would be to use delegate and take advantage of event bubbling to capture events on elements that may not yet exist. This is very easy, especially as you can work on the existing selection to provide a context:

$(document).ready(function () {
    $("img.tile").click(function () {
        var actid = $(this).data().id;
        $("#lz")
            .load("/dialog/pre?actid=" + actid)
            .delegate("#btnCheck", "click", function () {
                alert("test");
            });
    });
});

This is functionally equivalent to the load examples, but will have slightly better performance in several ways.

lonesomeday
  • 233,373
  • 50
  • 316
  • 318
  • Read the description of the live and delegate calls on the jQuery. Not sure I understand the difference. Why do we need two calls? – BuddyJoe Jun 21 '11 at 20:40
  • @tyndall [SO question comparing `delegate` and `live`](http://stackoverflow.com/questions/4204316/jquery-live-vs-delegate). What do you mean by "two calls"? – lonesomeday Jun 21 '11 at 20:41
  • I meant two methods. Looking at the other question now. – BuddyJoe Jun 23 '11 at 01:24
1

Try:

$(document).ready(function() {
    $("img.tile").click(function() {
    var actid = $(this).data().id;
    $("#lz").load("/dialog/pre?actid=" + actid);
    $("#btnCheck").live('click', function() {
        alert("test");
    }); });

This will pick up any elements added to the dom after the load event. A better way might be to use .delegate()

Stuart Burrows
  • 10,824
  • 2
  • 34
  • 33
  • Should it work if the code had the $("#btnCheck").live() outside of the click function - second line? It should right? Since it accounts for things that just show up in the DOM later right? Can't get live or delegate to work this way. – BuddyJoe Jun 23 '11 at 01:42
  • Nevermind it worked. Mis-named my button. – BuddyJoe Jun 23 '11 at 01:48
  • no worries - I should mention (as above) that `.delegate()` is considered the better method for several reasons (best seen in the linked question). I've not yet gotten into the habit of using it but am meaning to! This is why I upvoted @lonesomeday's answer - it is better!! – Stuart Burrows Jun 23 '11 at 08:14