0

The below code works great, except I want to access the data returned in my function but the object hasn't finished loading yet so I cannot access the object attributes?

 $images = $loaded_data.find('img').filter(function () {
     if ($(this).attr('src').match(/\.(jpg|png|gif)$/i)) {
        return $(this);
    }
  })

var $image_first = $images.filter(function () {
var theImage = new Image();

    theImage.src = $(this).attr("src");
    $(theImage).load(function () {
        if (theImage.width > 200) {
            goodImages = $(this);
            return goodImages;
        }

    });
}).first();

alert($image_first.attr('src'))

How can I prevent the alert from running until the above code has run?


To explain what I am trying to do.

I am loading in a block of html, filtering it to pull out all images with a width of over 200 then taking the first one and using this as the source URL for a news article.

chris
  • 605
  • 1
  • 9
  • 27
  • 2
    you can't, without removing the alert from that location and placing it elsewhere. – Kevin B Nov 18 '13 at 21:54
  • Where would I put it? – chris Nov 18 '13 at 21:54
  • 1
    you would need to first implement a callback into your code that executes when all of the images are done loading. The alert would go inside said callback. – Kevin B Nov 18 '13 at 21:55
  • @adeneo there isn't an ajax call here, though i guess the concept is the same. – Kevin B Nov 18 '13 at 21:56
  • @KevinB beat me to it. `.load()` takes a callback function in the `complete` action. See the [API](http://api.jquery.com/load/). – EmmyS Nov 18 '13 at 21:56
  • @EmmyS wrong api link, this isn't load-ajax, it's load-event – Kevin B Nov 18 '13 at 21:57
  • @KevinB - and that's .... wait for it ..... deprecated! – adeneo Nov 18 '13 at 21:58
  • So what are the callback options for non ajax loads? – chris Nov 18 '13 at 22:00
  • use the load event, just not with the shortcut method. Also, you should bind to said event before setting the src attribute, otherwise you will run into cross-browser issues. – Kevin B Nov 18 '13 at 22:00
  • `theImage.onload = function() {....` springs to mind, and adding a complete trigger sounds like a good idea as well. – adeneo Nov 18 '13 at 22:01
  • @KevinB - you're right; my mistake. Just FYI, OP - there's a big yellow Caveat box on the [api page](http://api.jquery.com/load-event/) for event load having to do with images (completely aside from it being deprecated.) – EmmyS Nov 18 '13 at 22:01
  • all but one of those issues (aside from it being depreciated) can be solved by binding to the load event first. – Kevin B Nov 18 '13 at 22:03
  • @chris loading html is an ajax call. Use the appropriate functions and their callbacks. – Mike H. Nov 18 '13 at 22:09
  • @MikeHometchko as someone pointed out above, using load in that manner is depreciated. – chris Nov 18 '13 at 22:12

1 Answers1

1
var images = $loaded_data.find('img').filter(function () {
    return this.src.match(/\.(jpg|png|gif)$/i);
}),
    promises = [],
    loaded   = [];

$images.each(function(i, image) {
    var img     = new Image(),
        promise = $.Deferred();

    img.onload = function() {
         promise.resolve();
    };

    img.src = image.src;
    promises.push(promise);
    loaded.push(img);
});

$.when.apply($, promises).done(function() {
    var $image_first = $(loaded).filter(function() {
        return $(this).width() > 200;
    }).first();

    alert($image_first);
});
adeneo
  • 312,895
  • 29
  • 395
  • 388