测试所有图片是否已加载

5

以下是我尝试编写的检测所有图片是否加载完成的能力:

for (var i = 0; i < imgCount; i ++) {
    loadArr[i] = false
    imgArr[i] = new Image()
    imgArr[i].src='img'+i+'.png'
    imgArr[i].onload = function() {
        loadArr[i] = true //but wait! At the end of
                          //the loop, i is imgCount
                          //so this doesn't work.
    }
}

问题在于一旦循环完成,变量 i 的值就是 imgCount。这意味着所有其他“已加载”标志都没有在它们的图像加载时设置为 true
是否有办法为图片添加一个“已加载”属性,或者有没有解决这个问题的方法?
3个回答

7

您需要使用闭包来定义onload函数:

for (var i = 0; i < imgCount; i ++) {
    loadArr[i] = false
    imgArr[i] = new Image()
    imgArr[i].src='img'+i+'.png'
    imgArr[i].onload = (function(i){
        return function(){ loadArr[i] = true }
    })(i);
}

这里有一个jsFiddle,演示了在类似情况下的工作原理。
此外,请注意,您当前选择的答案解决方案实际上并不起作用。
imgArr[i].onload = (function() {
        loadArr[i] = true;
    })();

此函数会立即执行。这意味着在循环中,loadArr 的每个元素都将设置为 true,并且 onload 事件也是如此。该代码在功能上与以下代码相同:

imgArr[i].onload = loadArr[i] = true;

1
谢谢,这是最简单和最有效的答案。(可以在2分钟内接受) - tckmn
等一下,实际上它不起作用(j被设置为最后一个索引)。 - tckmn

1

您必须像这样将索引值传递给匿名函数:

for (var i = 0; i < imgCount; i++) {
    loadArr[i] = false
    imgArr[i] = new Image()
    imgArr[i].src = 'img' + i + '.png'
    imgArr[i].onload = function (index) {
        return function () {
            loadArr[index] = true //but wait! At the end of
            //the loop, i is imgCount
            //so this doesn't work.
        };
    }(i);
}

我认为你可能是想表达:(function(i){ imgArr[i].onload = function(){...}; })(i); - Matt Coughlin

-1
这就是为什么闭包被创造出来的原因!你的循环几乎瞬间运行完毕,而第一张图片加载之前它就已经结束了。所以 i==imgCount 立即成立,"跳过"了所有其他值。闭包可以避免这种情况,并将每个 i 的值影响到不同的图像上。
然而,在你的情况下,我确实会给每个图像添加一个 "loaded" 属性。
// Construct your image array
for (var i = 0; i < imgCount; i++) {
    imgArr[i] = new Image();
    imgArr[i].src='img'+i+'.png';
}

//Then iterate over the array, adding a 'loaded' attribute when it occurs
imgArr.each(function(){
    $(this).onload(function() {
        $(this).attr('loaded','true');
    });
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接