Загрузить картинку по клику и показать плейсхолдер, успех и ошибку
На каждый клик кнопки загружать картинку в контейнер. Пока грузится — показать серый плейсхолдер; при успешной загрузке — показать картинку; при ошибке — красный фон ошибки. Повторный клик заменяет то, что есть. Используйте события жизненного цикла загрузки элемента изображения.
function onButtonClick(container, src) {
// ваш код здесь
}
Допишите реализацию.
Очистить контейнер (replaceChildren()), создать img, задать серый фон-плейсхолдер и навесить обработчики ДО установки src: img.onload показывает картинку, img.onerror ставит красный фон. Установка src последней запускает загрузку, и срабатывает ровно одно из двух событий. Очистка вначале означает, что повторный клик заменяет прошлый результат.
- ✗Задавать
srcдо навешиванияonload/onerror, рискуя пропустить событие у закэшированной картинки - ✗Ожидать, что загрузка картинки синхронна (читать
completeсразу послеsrc), а не событийна - ✗Забывать сначала очистить контейнер, из-за чего клики копят картинки вместо замены
- →Почему навешивать
onload/onerrorдо присваиванияsrc? - →Какое событие срабатывает при битом URL картинки, а какое при успехе?
Решение
Навесить onload/onerror до установки src, который и запускает загрузку.
function onButtonClick(container, src) {
container.replaceChildren(); // заменяем прошлый результат
const img = document.createElement('img');
img.style.backgroundColor = 'grey'; // плейсхолдер на время загрузки
img.onload = () => {
img.style.backgroundColor = '';
console.log('loaded');
};
img.onerror = () => {
img.style.backgroundColor = 'red';
};
img.src = src; // запускает загрузку — сработает ровно одно из событий
container.append(img);
}
Как это работает
Загрузка изображения асинхронна и событийна, а не синхронна. Поэтому обработчики onload и onerror навешиваются ДО присваивания src: само присваивание запускает загрузку, и если зарегистрировать слушатели после, у закэшированной картинки событие можно пропустить.
Серый фон работает плейсхолдером, пока картинка грузится. При успехе onload его убирает; при битом URL срабатывает onerror и ставит красный фон. replaceChildren() в начале гарантирует, что повторный клик заменяет прошлый результат, а не добавляет ещё одну картинку.