确定jQuery load()何时完成加载多个图像

时间:2014-07-14 21:37:56

标签: javascript jquery ajax json

我有一个脚本,它使用jQuery的getScript()函数从tumblr帐户动态加载博客帖子。

脚本响应是一个JSON结构tumblr_api_read,其中包含(除其他外)图像网址。

function read(blogName) {
    var imageUrls = [];
    $.getScript("http://" + blogName + ".tumblr.com/api/read/js", function() {
        imageUrls = getImageUrls(tumblr_api_read.posts); // returns an array of URLs to use as img src attributes
    }).done(function(script, textStatus) {
        loadImages(imageUrls);
        processTumblrResponse(); // ### ONLY EXECUTE WHEN IMAGES ARE LOADED!!
    });
}

我在函数loadImages()中使用imageUrls数组,通过jquery-built var <img/>$temporaryImageContainer注入DOM,然后进行一些进一步的处理。

var imgAjaxComplete = false;
var imgCount = 0;

function loadImages(imageUrls, $temporaryImageContainer) {
    while (!imgAjaxComplete) {
        for (srcKey in imageUrls) {
            var $image = $("<img>", {"id" : "imageUrl" + srcKey, "src" : imageUrls[srcKey]})
                .load(function() {
                    if (!this.complete || typeof this.naturalWidth == "undefined" || this.naturalWidth == 0) {
                        console.log("Error loading image: " + imageUrls[srcKey]);
                    } else {
                        $temporaryImageContainer.append($image);
                        console.log("Loaded image: " + imageUrls[srcKey]);
                    }
                });
            ++imgCount;
        }
        if (imgCount == imageUrls.length) {
            imgAjaxComplete = true;
            imgCount = 0;
        }
    }
    console.log("loadImages() complete");
}

function processTumblrResponse() {
    console.log("Images loaded. Running processTumblrResponse()");
    // further processing here...
}

问题在于,for中的loadImages()循环在其他任何事情之前执行(我认为这无论发生了什么)并且它只会尝试加载最后一张图片src在imageUrls n次(其中n是imageUrls.length)。

在执行额外处理之前,是否可以确定注入DOM的所有图像何时完成加载?

JSON太大了,无法发布到此处,但请告诉我上下文是否需要。

1 个答案:

答案 0 :(得分:2)

用此处替换您的函数loadImages

function loadImages(imageUrls, $temporaryImageContainer) {
        for (srcKey in imageUrls) {
            var $image = $("<img>", {"id" : "imageUrl" + srcKey, "src" : imageUrls[srcKey]})
                .load(function() {
                    if (!this.complete || typeof this.naturalWidth == "undefined" || this.naturalWidth == 0) {
                        console.log("Error loading image: " + imageUrls[srcKey]);
                    } else {
                        $temporaryImageContainer.append($image);
                        console.log("Loaded image: " + imageUrls[srcKey]);
                    }
                    imgCount++;
                    checkIfImagesAreLoaded();
                });
        }
}
function checkIfImagesAreLoaded() {
    if (imgCount === imageUrls.length) {
        imgCount = 0;
        imgAjaxComplete = true;
        console.log("loadImages() complete");
    }
}

至于解释,for循环在其他任何事情之前完成,因为jQuery load函数只在加载图像时执行作为参数传入的方法,因此不会立即调用它。

修改 您不应该在Javascript中使用for (x in array),因为此循环用于迭代对象的属性。不幸的是,最佳做法是使用for (var i = 0; i < length; i++) ...

请参阅W3Schools获取循环文档here

你也可以使用:

yourArray.forEach(function(item) {
    //Do crazy stuff here
});

但是forEach()是ES5的一部分,在IE8及以下版本的旧浏览器中不支持它。