Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery variable scope in function

I have a problem with jQuery.

I wanted to get the real width/height of an img.
Now I used this function to get it:

var imageSize = function(image) {
    var realImageSize = { };

    $("<img/>") // Make in memory copy of image to avoid css issues
    .attr("src", $(image).attr("src"))
    .load(function() {
        realImageSize.width = this.width;   // Note: $(this).width() will not
        realImageSize.height = this.height; // work for in memory images.

        alert(realImageSize['height']); // Valid height
    });

    alert(realImageSize['height']); // Undefined

    return realImageSize;
}

So I'm copying the image in memory, and then I get and set the images real size in the .load method.

Now, the problem is that the var realImageSize variable isn't available in this scope for some reason. Can anyone tell me why?

like image 242
IluTov Avatar asked Jun 11 '26 13:06

IluTov


1 Answers

That's not a problem of scope, it's fine, but a problem of synchronicity : you're reading the value before the load callback has been executed.

The callback you give as argument to load isn't executed immediately but only after the image has been loaded.

The usual solution is to not return a value but provide a callback :

var fetchImageSize = function(image, callback) {
    $("<img/>") // Make in memory copy of image to avoid css issues
    .load(function() {
        var realImageSize = { };
        realImageSize.width = this.width;   // Note: $(this).width() will not
        realImageSize.height = this.height; // work for in memory images.
        callback(realImageSize);
    }).attr("src", image.src);
};

fetchImageSize(myImage, function(realImageSize){
    alert(realImageSize['height']); // NOT Undefined
});

Note that you should always set the src after you set the onload callback. Some browsers, if you have the image in cache, might not call the onload callback if you set it after you set the source.

like image 197
Denys Séguret Avatar answered Jun 14 '26 03:06

Denys Séguret