Home › Forums › JavaScript › Can I sync up multiple image onload calls?
- This topic is empty.
-
AuthorPosts
-
December 29, 2011 at 2:22 pm #35881
noahgelman
ParticipantI want a function to run when specific images are loaded, but I don’t know how to wait for both to load before running. I only know how to chain them, like below:
Image1 = new Image();
Image1.src = 'image1-link.jpg';
Image2 = new Image();
Image2.src = 'image2-link.jpg';
Image1.onload = function() {
Image2.onload = function() { ... }
}The downside to this is it has to wait till Image1 completely loads before getting the second. I want to try something like this:
Image1 = new Image();
Image1.src = 'image1-link.jpg';
Image2 = new Image();
Image2.src = 'image2-link.jpg';
(Image1 && Image2).onload = function() { ... }How can I do this?
December 29, 2011 at 7:08 pm #93673Mottie
MemberHi Noah!
Actually recently blogged a snippet of code/mini plugin that basically does this.
Here is the code:
/*
Check if all images are loaded
- Callback occurs when all images are loaded
- image load errors are ignored (complete will be true)
- Use:
$('.wrap img').imagesLoaded(function(){
alert('all images loaded');
});
*/
jQuery.fn.extend({
imagesLoaded: function( callback ) {
var i, c = true, t = this, l = t.length;
for ( i = 0; i < l; i++ ) {
if (this.tagName === "IMG") {
c = (c && this.complete && this.height !== 0);
}
}
if (c) {
if (typeof callback === "function") { callback(); }
} else {
setTimeout(function(){
jQuery(t).imagesLoaded( callback );
}, 200);
}
}
});If you use
$(window).load(){ /* code here */ });
then you already know all images are loaded. But if you lazy load or add more images after the page has loaded, this is an alternative method.Here is how to use it to run the callback after multiple images have finished loading:
$(function(){
$('.wrap img').imagesLoaded(function(){
alert('all images loaded');
});
});Or, if you only have one image, just target that image
$('img#fred').imagesLoaded(function(){
alert('Fred!');
});If there are no images in your selector, it automatically runs the callback by default.
December 29, 2011 at 7:30 pm #93677noahgelman
ParticipantThanks, but not quite what I needed. I should have been more specific. These images aren’t been loaded into
tags, I’m using them in an HTML5 canvas. The user is able to change what’s drawn on the canvas via buttons and I want to make sure the images related to that are all loaded up before running all my other code.
December 29, 2011 at 7:52 pm #93678Mottie
MemberIt should be the same basic idea… I’m still learning canvas, but it still needs to load images before it can render them, right?
December 29, 2011 at 8:02 pm #93679noahgelman
ParticipantYes, it has to load the image first to use its data to draw on the canvas.
December 30, 2011 at 1:41 pm #93731noahgelman
ParticipantHere are 2 answers via stack overflow:
// loader will 'load' items by calling thingToDo for each item,
// before calling allDone when all the things to do have been done.
function loader(items, thingToDo, allDone) {
if (!items) {
// nothing to do.
return;
}
if ("undefined" === items.length) {
// convert single item to array.
items = [items];
}
var count = items.length;
// this callback counts down the things to do.
var thingToDoCompleted = function (items, i) {
count--;
if (0 == count) {
allDone(items);
}
};
for (var i = 0; i < items.length; i++) {
// 'do' each thing, and await callback.
thingToDo(items, i, thingToDoCompleted);
}
}
function loadImage(items, i, onComplete) {
var onLoad = function (e) {
e.target.removeEventListener("load", onLoad);
// this next line can be removed.
// only here to prove the image was loaded.
document.body.appendChild(e.target);
// notify that we're done.
onComplete(items, i);
}
var img = new Image();
img.addEventListener("load", onLoad, false);
img.src = items;
}
var items = ['http://bits.wikimedia.org/images/wikimedia-button.png',
'http://bits.wikimedia.org/skins-1.18/common/images/poweredby_mediawiki_88x31.png',
'http://upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/30px-Commons-logo.svg.png',
'http://upload.wikimedia.org/wikipedia/commons/3/38/Icons_example.png'];
loader(items, loadImage, function () {
alert("done");
});and here is a jsFiddle link for you http://jsfiddle.net/8baGb/1/
Second solution:var imageCollector = function(expectedCount, completeFn){
var receivedCount;
return function(){
if(++receivedCount == expectedcount){
completeFn();
}
};
}();
var ic = imageCollector(2, function(){alert("Done!");});
Image1.onload = ic;
Image2.onload = ic;And here is a link to the Stack Overflow thread
September 5, 2014 at 4:19 am #181778julmot
ParticipantI had the same problem like you. I wanted to wait for multiple callbacks. Because I did not found any plugin I built a plugin for that. You can define a stack of images and on which element you want them to be appended. Your callback function will be called after all elements are successfully added to the defined element and are all loaded. You can use the same for JavaScripts.
Usage:
var requireFile = new jm.RequireFile(); requireFile.addStackToDOM({ // The stack with the images to load 'stack': [ 'exampleFiles/image.png' ], // The selector where the image should appear, // if non is defined it will be appended to the <body>-element 'insertInto': '#load-images-here', // The callback if all scripts are loaded 'completed': function(){ alert('Hey all my images are loaded'); } });
-
AuthorPosts
- The forum ‘JavaScript’ is closed to new topics and replies.