JQuery - Calling function after image load

1.9k views Asked by At

So I have two functions. One to load the image and the other to resize its container element. Naturally the image element needs to be loaded, before any measurements can be taken. It looks something like this:

var imgEl;

loadImage(imgSrc);
// only call the below, once the above has finished loading and appending the image.
resizeModal();

function loadImage(imgSrc) {
    var image = new Image();
    image.src = imgSrc;
    image.onload = function() {
        imgEl = $('<img src='+image.src+'/>');
        imgEl.prependTo(modal); 
    }
}

function resizeModal() {

    // Do stuff based off the imgEl once it's been loaded and appended 
    var width = imgEl.width();
    modal.width(width)

}

I've tried using $.Deferred, but I'm apparently missing something, as "B" always gets logged before "A":

var imgEl;

loadImage(imgSrc).done( resizeModal() )

function loadImage(imgSrc) {

    var def = $.Deferred();

    var image = new Image();
    image.src = imgSrc;
    image.onload = function() {
        imgEl = $('<img src='+image.src+'/>');
        imgEl.prependTo(modal); 

        console.log("A");
        def.resolve();

    }

    return def;
}

function resizeModal() {

    console.log("B");

    // Do stuff based off the imgEl once it's been loaded and appended 
    var width = imgEl.width();
    modal.width(width)

}
2

There are 2 answers

6
Felix Kling On BEST ANSWER

That's because you are explicitly calling resizeModal before the promise is resolved:

loadImage(imgSrc).done( resizeModal() )

Just like with foo(bar()), this will call resizeModal and pass its return value to done().

You want to pass the function itself instead:

loadImage(imgSrc).done(resizeModal)

This basically means "call resizeModal once you are done".

1
Michael Christensen On
var loadImage = function(imgSrc, callback) {
    var imgEl;
    var image = new Image();
    image.src = imgSrc;
    image.onload = function() {
        imgEl = $('<img src='+image.src+'/>');
        imgEl.prependTo(modal); 
    }
    callback(imgEl);
}

var resizeModal = function(imgEl) {
    // Do stuff based off the imgEl once it's been loaded and appended 
    var width = imgEl.width();
    modal.width(width)
    return width;  // or whatever you are trying to get from this.
}

var finalOutput = loadImage(imgSrc, resizeModal);

Have you tried a structure like this?