This is the code I use to preload images, I'm not sure if it's the best one. My question is, how can I fire and event, for an example alert(); dialog after is has finished loading all the images?
var preload = ["a.gif", "b.gif", "c.gif"];
var images = [];
for (i = 0; i < preload.length; i++) {
images[i] = new Image();
images[i].src = preload[i];
}
You can use the new "$.Deferred" if you like:
var preload = ["a.gif", "b.gif", "c.gif"];
var promises = [];
for (var i = 0; i < preload.length; i++) {
(function(url, promise) {
var img = new Image();
img.onload = function() {
promise.resolve();
};
img.src = url;
})(preload[i], promises[i] = $.Deferred());
}
$.when.apply($, promises).done(function() {
alert("All images ready sir!");
});
Might be a little risky to leave the Image objects floating around, but if so that could be fixed easily by shifting the closure. edit in fact I'll change it myself because it's bugging me :-)
Since your tags include jQuery, here's what I would do in jQuery, with heavy inspiration from this related answer:
function preloadImages(images, callback) {
var count = images.length;
if(count === 0) {
callback();
}
var loaded = 0;
$.each(images, function(index, image) {
$('<img>').attr('src', image).on('load', function() { // the first argument could also be 'load error abort' if you wanted to *always* execute the callback
loaded++;
if (loaded === count) {
callback();
}
});
});
};
// use whatever callback you really want as the argument
preloadImages(["a.gif", "b.gif", "c.gif"], function() {
alert("DONE");
});
This relies on the callback to jQuery's load function.
I wouldn't use the related answer simply because I don't like mucking around with Javascript's built-in prototypes.
I've seen something used to correct behavior on Masonry nice jQuery plugin (a plugin used to make nice layout composition on pages). This plugin had problems with blocks containing images and should delay his work when the images are loaded.
First solution is to delay on the onLoad event instead of document.ready. But this event can be quite long to wait for. So they use jquery.imagesloaded.js which can detect that all images in a div are loaded; especially this very short and nice code can handle cached images which does not fire the load event sometimes.
Today I needed to preload images and execute some code only after all images are loaded, but without jQuery and using Ionic2/Typescript2. Here's my solution:
// Pure Javascript Version
function loadImages(arrImagesSrc) {
return new Promise(function (resolve, reject) {
var arrImages = [];
function _loadImage(src, arr) {
var img = new Image();
img.onload = function () { arr.push([src, img]); };
img.onerror = function () { arr.push([src, null]); };
img.src = src;
}
arrImagesSrc.forEach(function (src) {
_loadImage(src, arrImages);
});
var interval_id = setInterval(function () {
if (arrImages.length == arrImagesSrc.length) {
clearInterval(interval_id);
resolve(arrImages);
}
}, 100);
});
}
// Ionic2 version
private loadImages(arrImagesSrc: Array<string>): Promise<Array<any>> {
return new Promise((resolve, reject) => {
...
function _loadImage(src: string, arr: Array<any>) {
...
}
...
}
You can use like this. Problematic url returns 'null'.
loadImages(['https://cdn2.iconfinder.com/data/icons/nodejs-1/512/nodejs-512.png', 'http://foo_url'])
.then(function(arr) {
console.log('[???]', arr);
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With