how to make sure images load sequentially

2019-02-28 07:10发布

问题:

Here i have a simple test code which loads a test of images in browser.Here i used asynchronous onload event to add image to dom after it finishes loading. Images load just fine.Problem is if i continuously reload the page multiple time image sequence change.As if image-2 loaded before image-1 ,sometimes image-3 loads first, etc.How i can make sure images load sequentially, like first load image1,then image2,image3 etc every time i load the page.How i can do that?

var images = ['cat1.png','cat2.jpg','cat3.jpg'];

var i = 0;
images.forEach(function(elem,index,arr){
   var image=new Image();
   image.onload = function(){
       document.body.appendChild(image);
       console.log(++i);
   };
   image.onerror = function(){
       console.log('error occured');

   } 
   image.src = elem;
   image.style.width = '300px';
   image.style.height = '300px';
});

回答1:

You should wait for the callback from the onload event. If it's fired you can iterate and load the next image. This makes sure the images will be loaded in the right order (as in array).

var images = [
    'http://d39kbiy71leyho.cloudfront.net/wp-content/uploads/2016/05/09170020/cats-politics-TN.jpg',
    'error',
    'https://s2.graphiq.com/sites/default/files/stories/t2/tiny_cat_12573_8950.jpg',
    'http://www.bharatint.com/img/categories/our-cat-shop-image.png'
], i = 0;

function loadImageArrayAsync(){
    var image = new Image();
    image.onload = function(){
        document.body.appendChild(image);
        if (i++ < images.length - 1) loadImageArrayAsync();
    };
    image.onerror = function(){
        if (i++ < images.length - 1) loadImageArrayAsync();
     }
    image.src = images[i];
    image.style.height = '300px';
    image.style.width = '300px';
}

loadImageArrayAsync();


回答2:

Here is another approach. It fires off all the image requests in a loop, then when a response is received it does a bit of processing to work out which images can be displayed. This way you don't have to wait for one image to finish loading before requesting the next. The code could probably do with tidying up but you get the idea...

    var urls = ["/Content/images/Chrysanthemum.jpg", "/Content/images/Desert.jpg", "/Content/images/Hydwewrangeas.jpg", "/Content/images/Jellyfish.jpg", "/Content/images/Koala.jpg"]
    var numImages = urls.length;
    var images = [numImages];
    var gotResponse = [numImages];
    var maxDisplayed = -1;

    function checkImages(index) {
        // Check if previous images have been displayed
        if (maxDisplayed == index - 1) {
            for (i = index; i <= numImages; i++) {
                // Check if we've received a response for this image
                if (gotResponse[i] !== true) {
                    break;
                }
                maxDisplayed = i;
                if (images[i] != null) {
                    console.log('Adding image ' + i);
                    document.body.appendChild(images[i]);
                }
            }
        }
    }

    function imageError(index) {
        console.log('Error loading image ' + index);
        images[index] = null;
        gotResponse[index] = true;
        checkImages(index);
    }

    function imageLoaded(index, image) {
        console.log('Loaded image ' + index);
        images[index] = image;
        gotResponse[index] = true;
        checkImages(index);
    }

    function loadImages() {
        $.each(urls, function(index, value) {
            var image = new Image();
            image.onload = function () {
                imageLoaded(index, image);
            }
            image.onerror = function () {
                imageError(index);
            }
            image.src = value;
            image.style.width = '300px';
            image.style.height = '300px';
        });
    }

    loadImages();

Sample output:

Error loading image 2
Loaded image 3
Loaded image 0
Adding image 0
Loaded image 1
Adding image 1
Adding image 3
Loaded image 4
Adding image 4