Если я загружаю несколько изображений с помощью цикла for, мне нужна только одна функция img.onload? - PullRequest
4 голосов
/ 04 октября 2011

Итак, я загружаю несколько изображений на несколько холстов в основном (одно изображение на холст / ctx - это слайд-шоу). Я хочу убедиться, что каждое изображение загружено до того, как оно попытается нарисовать изображение на холсте.

Вот код ...

  • В примере 1 я использую 3 события загрузки (по одному для каждого изображения)
  • В примере 2 я использую одно событие onload, но это последнее изображение, которое вызывается в цикле for

Вопрос: Могу ли я использовать Пример 2 и быть уверенным, что если загружено последнее изображение, то также должны быть загружены изображения перед этим?

Также ---- Я уже пытался это сделать, но можно ли все это сделать внутри цикла for? Я не смог заставить его работать. См. Пример 3

Пример 1 3 событий загрузки

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);
    };

Пример 2 только последнее событие загрузки

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);
    };

Пример 3 одна загрузка в цикле for для выполнения всех событий загрузки

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);
        };

    }

Я предполагаю, что не могу сделать пример 3, потому что изображение, вероятно, не будет загружено к тому времени, когда цикл for запускается второй раз и перезаписывает событие onload для следующего изображения, таким образом стирая событие onload для предыдущего изображения. Правильно?

1 Ответ

10 голосов
/ 04 октября 2011

У вас будут проблемы с областью видимости последнего цикла for из-за замыканий.Чтобы что-то подобное сработало, вы захотите выйти из замыкания, заключив свое функциональное назначение в его собственную функцию. Эта статья объясняет это хорошо.

В идеале, ваш последний цикл 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];
}

Также имейте в виду, что вам нужно будет присвоить атрибут img.src ПОСЛЕ того, как обработчик загрузкибыли определены для некоторых разновидностей IE. (этот маленький кусочек на прошлой неделе стоил мне часа устранения неполадок.)

...