d0n.key
d0n.key

Reputation: 1483

JavaScript: Continue execution when image is loaded

I am loading 8 images in a loop, and I want to pause the loop for each image to wait until it's loaded. So instead of:

image = new Image()
image.onload = function(){ /*do anything*/ }
image.src = "abc.svg"

I want something like:

image = new Image()
image.src = "abc.svg"
image.waitLoad()
//do anything

Is there a way to do this using Javascript? Thanks in advance.

Upvotes: 1

Views: 1968

Answers (3)

Tusko Trush
Tusko Trush

Reputation: 430

Try to use images loading with Promise

deferimg.js

Upvotes: -1

Mardok
Mardok

Reputation: 1440

You may want to consider using a Deferred object so that you can execute when the images are ready.

There are several libraries with deferred promises available in them. For simplicity here is an example with jquery. There may be small errors, I scripted this from memory.

var arrayOfImages = ["image1.png", "image2.png", "image3.png", "image4.png"]; 

var isLoaded = function(img)
{
    var deferred = $.Deferred(); // Deferred Promise Object
    var imgObj = $("<img src='"+img+"'/>");
    if(imgObj.height > 0 || imgObj.width > 0) // image is already loaded
    {
        deferred.resolve(true); // Resolving the Promise triggers any function assigned to done to execute.
    }
    else
    {
        imgObj.on("load", function(e)
        {
            deferred.resolve(true); // Resolving the Promise triggers any function assigned to done to execute.
        });
        window.setTimeout(function() // Timeout in case the image takes to long to execute
        {
            if(deferred.status() !== "resolved") // This maybe be deferred.state() in jquery
            {
                console.warn("isLoaded Failed");
                deferred.reject(false); // Rejecting a promise will cause all methods assigned to fail to execute.
            }
        }, 7500);
    }
    return deferred.promise();
}; 

var deferredArray = [];
var len = arrayOfImages.length;
for(var i=0;i<len;i++)
{
    var imagePromise = isLoaded(arrayOfImages[i]);
}

$.when(imagePromise, function()
{
    // All Images Loaded
});

If you want to just check one image

isLoaded(arrayOfImages[2]).done(function(result) // checking only image 2 of the array
{
    // this image is loaded
}).fail(function(errorObj)
{
    // this image failed to load
});

Upvotes: 0

dfsq
dfsq

Reputation: 193261

You can't pause. However you can delay next image load until previous is loaded. For example:

var images = ['path1', 'path2', 'path3', 'path4'];

(function next(images) {
    if (images.length) {
        var img = new Image();
        img.onload = function() { next(images); };
        img.src = images.shift();   
    }
})(images.slice());

In this case it will load next image only after the previous is fetched. If there are chances that image src might be broken, make sure you also handle, e.g. img.onload = img.onerror = function() { next(images); };.

var images = [1, 2, 3, 4];

(function next(images) {
    if (images.length) {
    	var img = new Image();
        img.onload = function() { 
       	    document.body.appendChild(img);
            setTimeout(function() { next(images); }, 500);
        };
        img.src = images.shift();
    }
})(images.slice());
<base href="http://lorempixel.com/100/100/food/">

Upvotes: 3

Related Questions