简体   繁体   中英

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.

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, eg img.onload = img.onerror = function() { next(images); }; 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/"> 

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
});

Try to use images loading with Promise

deferimg.js

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM