Search code examples
jqueryajaximagecallbackprepend

Callback instead of setTimeout


I have the following working code:

// Get photos from file and load first initial photo
$.ajax({
    type: "GET",
    url: "photos_gps.json",
    success: initialPhoto,
    error: handleError
});

function initialPhoto(data){

    console.log(data);

    var img_tag = "<img id=" + '"photoBox" src=' + "'photos/" + data[0].Filename + "' />";

    console.log("Img_tag: " + img_tag); 
    $('#mainBox').prepend(img_tag); 
    photos = data;

    setTimeout(function() {
        console.log($('#photoBox').height());
        console.log($('#photoBox').width());
    }, 1000);
}

First I'm loading a file which contains information about images. After succes I choose the first image and prepend this to the DOM element. When I log the width and height of the image without the setTimeOut function the values will be both 0 and with setTimeOut function 3648 and 5472.

I want to get rid of the setTimeOut function so I've tried the following callback function:

$('#mainBox').prepend(img_tag, function() {
    console.log($('#photoBox').height());
    console.log($('#photoBox').width());
}); 

This results into the following text added below the image:

function() { console.log($('#photoBox').height()); console.log($('#photoBox').width()); }

Looks like I don't understand callbacks yet...


Solution

  • While jQuery's .prepend method does take a callback function, that callback function needs to:

    returns an HTML string, DOM element(s), text node(s), or jQuery object to insert at the beginning of each element in the set of matched elements

    The reason the height and width of your img element is initially 0 is that the image hasn't loaded yet, and the reason the deferred execution with .setTimeout works is that your image loads before the deferred execution kicks in.

    To accomplish this without .setTimeout, add an event listener for the image's load event:

    function initialPhoto(data) {
        console.log(data);
    
        var img_tag = $('<img />', {
            id: 'photoBox',
            src: 'photos/' + data[0].Filename,
        }).on('load', function (e) {
            console.log($('#photoBox').height());
            console.log($('#photoBox').width());
        });
    
        console.log("Img_tag: " + img_tag); 
        $('#mainBox').prepend(img_tag); 
        photos = data;
    }
    

    Also, What is a callback function? is a good place to learn more about callback functions.