0

I am currently getting the size of some images in an each() statement.

I am binding a function to it's load event. Although, I need it to obtain the images height before continuing code execution.

$(window).load(function () {

      $("element").each( function() {
            /*
            .
            .
            .
            .
            */
            var containerHeight = $(this).height();
            var imgHeight = 0;

            //get the size of the full image.
            var imgLoad = $("<img />");
            imgLoad.attr("src", imgSrc);
            imgLoad.bind("load", function () { imgHeight = this.height; });

            heightDiff = (imgHeight - containerHeight);

            //some methods are called...
            //imgHeight is still set to 0
      });
});

I considered using .trigger("custom-event")

and then checking if it was called with Jquerys .when() method

But is there a easier (if not better) way in doing this?

Regards,

Jake Dev
  • 19
  • 6
  • what is your actual requirement – Arun P Johny May 08 '15 at 07:01
  • 2
    This sounds like an XY problem. What exactly is it that you need to achieve? – Rory McCrossan May 08 '15 at 07:01
  • all code that depends on `imgHeight` should be inside teh load callback – Arun P Johny May 08 '15 at 07:01
  • Arun P Johny, what if I have a loop? – Jake Dev May 08 '15 at 07:14
  • Your question is misleading due to misunderstanding of processes happening. `bind` completes synchronously. The event `load` which you need is performed asynchronously by browser. And there is nothing you can do about it, but to handle multiple asynchronous events. So the solution would be to use `when` or any other promise library if you need to process heights of all images when they all load. Or one by one as stated by @Arun – Kirill Slatin May 08 '15 at 07:23
  • Consider using a [preloader](https://github.com/thinkpixellab/PxLoader), that will trigger an event when all images are loaded [even [this one](https://github.com/desandro/imagesloaded)]. – moonwave99 May 08 '15 at 07:33
  • @JakeDev once you state the overall requirement we can look at a solution... which might involve using promise – Arun P Johny May 08 '15 at 08:05

3 Answers3

1

The ever so classic "how can I return values from an asynchronous function" problem.

You can't, period. Use callbacks.

$("element").each(function () {
    var containerHeight = $(this).height(),
        imgSrc = "something";

    $("<img />", { src: imgSrc })
    .appendTo("#whatever")
    .on("load", function () { 
        var $img = $(this),
            heightDiff = ($img.height() - containerHeight);

        //some methods are called...
    });
});
Community
  • 1
  • 1
Tomalak
  • 332,285
  • 67
  • 532
  • 628
0

I think your doing it almost right, the window.load is triggered when all elements (including the images) are loaded. to obtain the height of each image use something like:

$(window).load(function(){

   // triggered when images are loaded

     $('img').each(function() {

          // get the height of each image
          var height = $(this).height();

      });
});
Michiel
  • 4,160
  • 3
  • 30
  • 42
0

You can't negotiate image loading be done synchronously, so you have to do all your work in the load event callback function:

var imgLoad = new Image();
imgLoad.onload = function() {
    var imgHeight = this.height,
    heightDiff = (imgHeight - containerHeight);
    // do stuff here
};
imgLoad.src = imgSrc; // load image
Ja͢ck
  • 170,779
  • 38
  • 263
  • 309