Search code examples
javascriptjqueryjquery-eventsjquery-onjquery-append

Appending data from a handler loaded after the script


I've made a site that displays a user's Facebook photos. The code below appends the photos to the div "facebook-images". This part works fine. The problem I have is that the images are being appended after the Javascript code below is loaded; so the handler "fb-image" is not created when the browser reads the click function code at the bottom, therefore it does not work.

I believe I need to use jQuery on(), but where? I've tried to put on() everywhere in the code below. I've tried to bind with append, I've tried live (which I know is deprecated but worth a shot). Nothing is working.

Any ideas?

<div class="target">
    
</div>
    
<div id="facebook-images">

</div>

<script>
    $.when(window.deferredes.fbLoaded, window.deferredes.fbLoggedIn).then(function () {
        $.getJSON('https://graph.facebook.com/me/photos?access_token=' + FB.getAccessToken(), function (data) {
            $.each(data.data, function (i, face) {
                $('#facebook-images').append("<div class='fb-image'><img src='" + face.source + "' ></div>");
            });
        });
    });

    $(".fb-image img").click(function () {
        $(".target").append("<h1>hi</h1>");
    });
</script>

Solution

  • The simplest way to fix this is to add the click handlers AFTER the images are inserted into the page.

    <script>
        $.when(window.deferredes.fbLoaded, window.deferredes.fbLoggedIn).then(function () {
            $.getJSON('https://graph.facebook.com/me/photos?access_token=' + FB.getAccessToken(), function (data) {
                $.each(data.data, function (i, face) {
                    $('#facebook-images').append("<div class='fb-image'><img src='" + face.source + "' ></div>");
                });
                $(".fb-image img").click(function () {
                    $(".target").append("<h1>hi</h1>");
                });
            });
        });
    
    </script>
    

    You can also use delegated event handling if you want. To do that, you set the event handler on a common parent that does exist at the time you run the event handling code with .on() and you use the delegated form of .on() by passing it a selector like this:

    <script>
        $.when(window.deferredes.fbLoaded, window.deferredes.fbLoggedIn).then(function () {
            $.getJSON('https://graph.facebook.com/me/photos?access_token=' + FB.getAccessToken(), function (data) {
                $.each(data.data, function (i, face) {
                    $('#facebook-images').append("<div class='fb-image'><img src='" + face.source + "' ></div>");
                });
            });
        });
    
        $("#facebook-images").on('click', ".fb-image img", function () {
            $(".target").append("<h1>hi</h1>");
        });
    </script>
    

    The delegated form of .on() works like this:

    $(selector of static parent).on(event, selector that matches dynamic object, fn);