Reputation: 169
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
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
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
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
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
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
Reputation: 907
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
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