Как определить статус загрузки изображений, не прикрепленных к DOM - PullRequest
2 голосов
/ 03 июня 2010

Я работаю над небольшим количеством JavaScript для отображения данных на <canvas>. Точки данных помечены одним из нескольких разных (маленьких) файлов изображений. Я пытаюсь заставить метод заговора ждать, пока все изображения не будут загружены. Моя лучшая попытка на данный момент такова:

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.

Ответы [ 3 ]

2 голосов
/ 03 июня 2010

Простите, если я ошибаюсь, но нет ли в вашей логике load недостатка? Что произойдет, если right.air будет загружен до left.air? Внутренние события load никогда не сработают, и тогда сюжет не начнется, не так ли?

Я бы сделал это по-другому: имейте четыре флага и соответствующее событие load установите свой собственный флаг на true. Проверьте в конце каждого события, установлены ли все четыре флага в значение true. Если да, то ты идешь.

И что говорит Балу: Вам нужно связать событие load перед назначением src.

1 голос
/ 03 июня 2010

Это должно сработать. Это гарантирует, что 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();
}
1 голос
/ 03 июня 2010

Привязать события load (), прежде чем указывать источник изображения

Или они могут быть загружены до создания события

И, как предлагает Пекка, создайте все события отдельно. Сохраните счетчик или проверьте свойство .complete для изображений, чтобы увидеть, все ли они загружены

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...