user2267395
user2267395

Reputation: 169

Why is image onload not working

I realize this is a common question asked by novice javascript programmers which I am. Console.log(img) and console.log("before onload") execute correctly but I never see an Image Loaded message.

AssetManager.loadImages = function(urls) {
   var images = [];
   var urlCount = urls.length;
   for (var i=0; i<urlCount; i++) {
      var img = new Image();
      images.push(img);
   }
   var urlsLoaded = 0;
   for (var i=0; i<urlCount; i++) {
      (function(img) {
         console.log(img);
         console.log("before onload");
         img.onload = function(e) {
            console.log("Image Loaded!");
            urlsLoaded++;
            if (urlsLoaded >= urlCount) {
               AssetManager.callback(images);
            }
         }
      })(images[i]);            
      images[i].src = urls[i];
   }
}

Upvotes: 10

Views: 55732

Answers (7)

ibrust
ibrust

Reputation: 174

My recommendation would be to, if possible, just use react native's image for this. The expo team appears to have certain rigid opinions on how the API should work... with react-native-image you can just use onLoadEnd and it'll fire regardless of whether the image was loaded from network or cache. Very simple. In my case I was only displaying 1 banner image with this, so I'm not worried about losing the performance optimizations that come along with expo image.

Upvotes: 0

Whip
Whip

Reputation: 2224

onload doesn't fire if the image is being loaded from cache. You can use the complete property to check for this case.

if(img.complete){
   // do the work
} else {
   img.onload = () => {
       // do the work
   }
}

You can use a function to keep the code DRY.

Upvotes: 14

Chends
Chends

Reputation: 1

I faced a similar problem. I noticed that my image .onload was not being called if the page is reloaded normally, if I reloaded the page using f12 + right click reload button and chose Empty Cache and Hard Reload, the .onload was called.

Upvotes: 0

kenecaswell
kenecaswell

Reputation: 7598

For anyone who made the same mistake as me - make sure onload is all lowercase and not camel case: onLoad.

This good:

img.onload = function () { };

This bad:

img.onLoad = function () { };

Upvotes: 9

Ehsan Jelodar
Ehsan Jelodar

Reputation: 1544

"img.onload" function when call in nested function not work exact

you need call "img.onload" function explicit in "$().ready (function(){ }" or "window.onload = function() { }"

e.g

$().ready (function(){ 

 var img = new Image();
 img.src = 'image.png';
 img.onload = function()
 {
  console.log("loaded");
 }
}

Upvotes: 1

Try var img = document.createElement("img");

or

AssetManager.loadImages = function(urls) {
    var images = new Array();
    var urlCount = urls.length;
    var urlsLoaded = 0;
    var leImg;
    for (var i=0; i<urlCount; i++) {
        leImg = document.createElement("img");
        leImg.onload = function(e){
            urlsLoaded++;
            if (urlsLoaded >= urlCount) {
               // AssetManager.callback(images); --> this is balls, still
            }
        }
        leImg.src = urls[i];
        _images.push(leImg);
    }

}

(not tested, and drunk)

Upvotes: 6

Matt Berkowitz
Matt Berkowitz

Reputation: 975

I'm not sure what the exact problem is with your code, but here's some code I wrote awhile back to handle the same problem (fiddle: http://jsfiddle.net/LJRSL/) There's some extra stuff in there that's probably not necessary :)

$.preloadImg = function (url, callback, to_len) { //to_length = image fetch timeout in ms
    var img = new Image(),
        $img = $(img),
        st = new Date().getTime(),
        to;

    if (callback && $.isFunction(callback)) {

        to = window.setTimeout(function () {
            callback.call(this, url, true);
        }, to_len || 5000);

    }


    $img
        .on('load', function () {
            to = window.clearTimeout(to);

            if ($.isFunction(callback))
                callback.call(this, url, false);
        })
        .attr('src', url)
        ;
    /*this is probably unnecessary*/
    if (img.complete) {
        $img.off('load');
        if ($.isFunction(callback)) {
            to = window.clearTimeout(to);

            callback.call(this, url);
        }
    }
};

$.preloadImg('https://www.google.com/images/srpr/logo4w.png', function(img) { $('#test').attr('src', img); alert('done'); });

and for good measure loading multiple:

$.preloadImgs = function (urls, callback, to_len) {
    var i = 0, c = 0;
    for (; i < urls.length; i++) {
        c++;
        $.preloadImg(urls[i], function (url, timedout) {
            if (--c === 0 && i >= urls.length - 1)
                callback.call(this, urls);
        }, to_len);
    }
};

You might try binding your event via addEventListener instead of onload =

Upvotes: 0

Related Questions