通过AJAX请求创建图像后等待图像加载

时间:2017-08-18 09:38:38

标签: javascript jquery ajax

我正在获取带有AJAX请求的图像(74个文件)。我正在将它们加载到一个数组中。然后我改变了一些调用函数changeMargins()的样式。问题是当图像尚未全部加载并准备就绪时调用该函数。

imageArray = new Array();     

$.ajax({
  url: url,
  success: function (data) {
    counter = 0
    $(data).find("a").attr("href", function (i, val) {
      if (val.match(/\.(jpe?g|png|GIF)$/)) { 
        imageArray[counter]= new imageItem(url + val)
        ++counter;  
      }
    });

    changeMargins(imageArray);

我如何等待完成图像元素上的AJAX 所有加载事件,然后继续处理?

1 个答案:

答案 0 :(得分:1)

这个问题最好通过“宣传”图像加载过程来解决,即创建一个在图像加载时解析的承诺。

有一个设计决定......是(a)吞下加载错误还是(b)允许任何个别错误导致整个过程失败。

假设(a),你会写这样的东西:

function loadImages() {
    return $.ajax({
        url: url,
        // other ajax params?
    }).then(function(data) {
        return $.Deferred(function(dfrd) { // promisify the entire image loading proceess
            var imageArray = [];
            var counter = 0; // tally of images that have either loaded or failed to load
            $(data).find('a').get().map(function(element) {
                // map a elements in data to an array of their hrefs
                return element.href;
            }).filter(function (href) {
                // filter out any non-jpe?g|png|GIF 
                return href.match(/\.(jpe?g|png|GIF)$/);
            }).forEach(function(val) {
                // for each match, create a Image() object, push onto the array, attach onload and onerror handlers, and set the `src` attribute.
                var img = new Image();
                imageArray.push(img);
                img.onload = function loadHandler() {
                    counter += 1;
                    if(counter == images.length) {
                        dfrd.resolve(imageArray);
                    }
                };
                img.onerror = function errorHandler() {
                    console.log(new Error('image ' + url + val + ' failed to load'));
                    // Here, you might choose to splice failed Images out of `imageArray`.
                    counter += 1;
                    if(counter == images.length) {
                        dfrd.resolve(imageArray);
                    }
                };
                img.src = url + val;
            });
        });
    }).then(function(imageArray) {
        changeMargins(imageArray);
        return imageArray;
    });
}

注意:

  • 更典型的是,人们会选择在最低级别(即每个Image()单独宣传)但承诺相当昂贵,因此有74张图片,最好是宣传 en masse
  • 通过宣传,并从loadImages()返回承诺,其来电者被告知完成了该过程 - 您可以链接loadImages().then(...)并在图片加载/失败时执行操作。