29.12.2008

JS: image.onload

Делал прелоадилку картинок и столкнулся с проблемой — в Опере у картинки иногда не срабатывал обработчик события onload.

Оказалось, проблема была в том, что я сначала задавал src и потом навешивал обработчик onload, а нужно делать наоборот. Причина проста: если картинка находится в кэше, то в Опере после задания src она загружается мгновенно, и событие onload срабатывает еще до того, как мы навесили обработчик onload.

Я наблюдал этот эффект только в Опере, хотя не исключаю, что может проявиться и в других браузерах.

Правильный код:

var image = document.createElement('img');
image.onload = function () {
    // вызывается всегда
    alert('image loaded');
};
image.src = 'test.jpg';

В общем, логика такая: сначала нужно задать обработчик события, и только потом делать действия, которые могут привести к возникновению этого события.

12 комментариев:

Анонимный комментирует...

Спасибо за инфу ..

Naoki комментирует...

Схожая проблема, не принимаются onload на картинках. Пробовал и так, и так - не помогло. Остальные браузеры ведут себя нормально. Буду дальше экспериментировать.

Семен комментирует...

Информация очень помогла в решении одной задачки. Спасибо!

Александр Пекур комментирует...

Спасибо, ценно. Редко в русскоязычном сегменте бывает что-то толковое.

japanes комментирует...

у меня такая ерунда в ИЕ6 была (делал маленькую галерею картинок, где надо прелодер показывать если картинка не загружена). спасибо помогло :)

Lesha комментирует...

можно еще опираться на размеры изображения.
Вот примерчик

Maksim комментирует...

Спасибо за информацию.

Столкнулся с проблемой в FF 3.5.7

toha.in комментирует...

Огромное спасибо. Очень полезная информация.

Алекс комментирует...

Да, проблема была, решена была таким же образом, наблюдалась помойму не только в опере.

vlsopin комментирует...

Привязку события к объекту проще всего сделать так:
this.onLoad=(оработчик событя)
При этом где в строке обработчик события не важно!

vlsopin комментирует...

Привязку события к объекту (картинке) просто сделать так: this.onLoad=(обработчик события). Расположение внутри тэга не важно.

meandre комментирует...

Если нет выбора, строить ли картинку динамически, т.е., она уже есть в html, я обычно поступаю так:
html:
<\img src="pic.png" onload="this.isLoaded = true;">
js:
var pic = $$('img')[0]
var onLoadPic = function () {
// обработчик
}
if (pic.isLoaded)
onLoadPic() // непосредственно вызываем обработчик
else // низагрузился =)
pic.on('load', onLoadPic) // откладываем

ну, в принципе всё. пример на prototype.js, но это же пример =)