Javascript 如何确定未连接到DOM的图像的加载状态

Javascript 如何确定未连接到DOM的图像的加载状态,javascript,jquery,image,Javascript,Jquery,Image,我正在使用javascript在上绘制数据。数据点由几个不同(小)图像文件中的一个标记。我正在尝试让plot方法等待所有图像加载。迄今为止,我最好的尝试是: var icon = { left : { air : new Image(), bone : new Image(), }, right : { air: new Image(), bone : new Image(), }, }; icon

我正在使用javascript在
上绘制数据。数据点由几个不同(小)图像文件中的一个标记。我正在尝试让plot方法等待所有图像加载。迄今为止,我最好的尝试是:

var icon = {
    left : {
        air : new Image(),
        bone : new Image(),
    },
    right : {
        air: new Image(),
        bone : new Image(),
    },
};

icon.left.air.src   = option.imgPath + 'left.air.png';
icon.right.air.src  = option.imgPath + 'right.air.png';
icon.left.bone.src  = option.imgPath + 'left.bone.png';
icon.right.bone.src = option.imgPath + 'right.bone.png';


function main() {
    Canvas.draw();

    // Make sure our image icons are loaded before we try to plot
    $(icon.left.air).load(function() {
        $(icon.right.air).load(function() {
            $(icon.left.bone).load(function() {
                $(icon.right.bone).load(function() {
                    Data.plot();
                });
            });
        });
    });
}
这在大多数情况下都能如期工作。有时,它会失败,并且不会绘制数据。插入几个console.log()语句表明脚本将在一系列.load()语句中以静默方式停止工作,但随后的代码将被执行

我的问题如下:我的方法正确吗?是否有一种方法可以将事件附加到我的图标对象,一旦加载了其中的所有图像,该事件就会触发


这是一个jquery插件,因此显然基于jquery的解决方案和普通javascript一样可以接受。

如果我错了,请原谅,但是您的
加载逻辑中没有缺陷吗?如果
right.air
left.air
之前加载,会发生什么情况?最里面的加载事件永远不会触发,绘图也不会启动,是吗

我会采取不同的做法:让四个标志和相应的
load
事件将自己的标志设置为
true
。在每个事件结束时检查是否所有四个标志都设置为true。如果是的话,你可以走了

baloo说的是:在指定
src
之前,需要绑定
load
事件,然后才能指向图像src的

或者在创建事件之前加载它们

就像佩卡建议的那样,把所有的事件都分开。
保留一个计数器或检查图像的.complete属性,查看它们是否都已加载

这应该可以解决问题。它保证在加载所有图像并且运行主函数之前,不会调用
Data.plot()

...

function collected(count, fn){
    var loaded = 0;
    return function(){
        if (++loaded === count){
             fn();
        } 
    }
}

// four calls + the trigger in 'main'
var onLoad = collected(5, function(){
    Data.plot();
});

icon.left.air.load = onLoad;
icon.right.air.load = onLoad;
icon.left.bone.load = onLoad;
icon.right.bone.load = onLoad;

// set the src AFTER load to make this reliable
icon.left.air.src   = option.imgPath + 'left.air.png';
icon.right.air.src  = option.imgPath + 'right.air.png';
icon.left.bone.src  = option.imgPath + 'left.bone.png';
icon.right.bone.src = option.imgPath + 'right.bone.png';

function main() {
    Canvas.draw();
    onLoad(); // this will be the last (or first, second, third, fourth) call needed to execut Data.plot();
}

@OP:将此与巴鲁的答案结合起来,应该可以解决问题。我明白你的意思,但有一个问题:当这一切完成时,我将得到11个不同的图标。我应该只测试一组标志吗?如果它们没有被加载,我是否应该使用一些小值的setInterval,然后再试一次?实际上,这是两个问题。@Rookwood-hmm。数组当然是一个很好的方法——或者像@Sean建议的那样,作为计数器。基本上,如果可以保证加载所有图像,只需加载
事件就足够了。当所有11个都加载时,最后一个将触发绘图(因为已达到所需的数字)。如果图像加载失败,绘图将不会启动。请查看@Sean的解决方案,也许它已经满足了您的需要。@OP:将此与Pekka的答案结合起来,应该可以解决问题。大多数浏览器在当前块(函数)完成之前不会开始加载图像。但是,是的,在设置SRC之前设置负载事件是一个很好的逻辑想法。实际上,这是可靠行为所必需的。一旦确认此解决方案有效(目前无法测试),将获得我的升级票。唯一需要注意的是,如果浏览器缓存了图像,.load事件显然不会触发。如果我用jquery$(img.load)包装它(函数(){onLoad();});它似乎工作得很好。感谢大家的投入。