javascript 如果我用 for 循环加载多张图片,我只需要一个 img.onload 函数吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7641588/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 00:46:52  来源:igfitidea点击:

If I load multiple images with the for loop, do I only need one img.onload function?

javascriptcanvasloadingonload

提问by Jacob

So I am loading multiple images onto multiple canvases basically (one image per canvas/ctx - its a slideshow). I want to make sure that each image is loaded before it attempts to draw the image onto the canvas.

所以我基本上将多个图像加载到多个画布上(每个画布/ctx 一个图像 - 它是幻灯片)。我想确保在尝试将图像绘制到画布上之前加载了每个图像。

Here is the code...

这是代码...

  • In Example 1 i'm using 3 onload events (one for each image)
  • In Example 2 i'm using one onload event, but it is the last image that gets called in the for loop
  • 在示例 1 中,我使用了 3 个 onload 事件(每个图像一个)
  • 在示例 2 中,我使用了一个 onload 事件,但它是在 for 循环中调用的最后一个图像

Question:Can i use Example 2 and be confident to assume that if the last image is loaded, then the images before must be loaded as well?

问题:我可以使用示例 2 并确信如果加载了最后一张图片,那么也必须加载之前的图片吗?

Also----I attempted this already, but can it all be done inside a for loop? I wasn't able to get it to work. See Example 3

另外----我已经尝试过这个了,但是这一切都可以在 for 循环中完成吗?我无法让它工作。参见示例 3

Example 13 onload events

示例 13 onload 事件

var img=[0,'slide1','slide2','slide3'];   

for (var i=1;i<=3;i++) {
        img[i] = new Image();
        img[i].src = '/images/slide' + i + '.png'
    }

    img[1].onload = function() { // checks to make sure img1 is loaded
        ctx[1].drawImage(img[1], 0, 0);
    };

    img[2].onload = function() { // checks to make sure img2 is loaded
        ctx[2].drawImage(img[2], 0, 0);
    };

    img[3].onload = function() { // checks to make sure img3 is loaded
        ctx[3].drawImage(img[3], 0, 0);
    };

Example 2only the last onload event

示例 2仅最后一个 onload 事件

var img=[0,'slide1','slide2','slide3'];   

for (var i=1;i<=3;i++) {
        img[i] = new Image();
        img[i].src = '/images/slide' + i + '.png'
    }

    img[3].onload = function() { // checks to make sure the last image is loaded
        ctx[1].drawImage(img[1], 0, 0);
        ctx[2].drawImage(img[2], 0, 0);
        ctx[3].drawImage(img[3], 0, 0);
    };

Example 3one onload in the for loop to do all the onload events

例3for循环中的一个onload来做所有的onload事件

var img=[0,'slide1','slide2','slide3'];   

for (var i=1;i<=3;i++) {
        img[i] = new Image();
        img[i].src = '/images/slide' + i + '.png'

        img[i].onload = function() { // checks to make sure all images are loaded
            ctx[i].drawImage(img[i], 0, 0);
        };

    }

I assume I can't do example 3 because an image probably won't be loaded by the time the for loop runs the second time and rewrites the onload event for the next image thus erasing the onload event for the prior image. Correct?

我假设我不能做示例 3,因为在 for 循环第二次运行时可能不会加载图像并重写下一个图像的 onload 事件,从而擦除前一个图像的 onload 事件。正确的?

回答by Daniel Szabo

You'll have scoping issues with the last for-loop because of closures. In order for something like this to work, you'll want to break out of the closure by encapsulating your functional assignment in it's own function. This articleexplains it well.

由于闭包,您将在最后一个 for 循环中遇到范围问题。为了让这样的事情起作用,您需要通过将您的功能分配封装在它自己的功能中来打破闭包。 这篇文章解释得很好。

Ideally, your last for-loop would look something like this:

理想情况下,您的最后一个 for 循环如下所示:

var images = [0,'slide1.png', 'slide2.png', 'slide3.png'];

// Assign onload handler to each image in array
for ( var i = 0; i <= images.length; i++ ){

   var img    = new Image();
   img.onload = (function(value){
       return function(){
           ctx[value].drawImage(images[value], 0, 0);
       }
   })(i);

   // IMPORTANT - Assign src last for IE
   img.src    = 'images/'+images[i];
}

Also, keep in mind that you'll need to assign the img.src attribute AFTER the onload handler has been defined for some flavors of IE. (this little tidbit cost me an hour of troubleshooting last week.)

另外,请记住,您需要在为某些 IE 定义 onload 处理程序后分配 img.src 属性。 (这个小花絮上周让我花了一个小时的时间进行故障排除。)