Определите, когда изображение не загружается в Javascript - PullRequest
81 голосов
/ 22 марта 2012

Есть ли способ определить, ведет ли путь к изображению к реальному изображению, т.е. определить, когда изображение не загружается в Javascript.

Для веб-приложения я анализирую файл xml и динамически создаю изображения HTML из списка путей к изображениям. Некоторые пути к изображениям могут больше не существовать на сервере, поэтому я хочу аккуратно завершить работу, обнаружив, какие изображения не удалось загрузить, и удалив этот элемент HTML img.

Примечание. Решения JQuery не могут быть использованы (босс не хочет использовать JQuery, да, я знаю, что я не начинаю). Я знаю способ определения в JQuery времени загрузки изображения, но не знаю, не получилось ли оно.

Мой код для создания элементов img, но как я могу определить, приводит ли путь img к ошибке загрузки изображения?

var imgObj = new Image();  // document.createElement("img");
imgObj.src = src;

Ответы [ 7 ]

91 голосов
/ 22 марта 2012

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

function testImage(URL) {
    var tester=new Image();
    tester.onload=imageFound;
    tester.onerror=imageNotFound;
    tester.src=URL;
}

function imageFound() {
    alert('That image is found and loaded');
}

function imageNotFound() {
    alert('That image was not found.');
}

testImage("http://foo.com/bar.jpg");

И мои симпатии к боссу, устойчивому к jQuery!

33 голосов
/ 19 сентября 2016

Ответ хороший, но он вносит одну проблему. Всякий раз, когда вы назначаете onload или onerror напрямую, он может заменить обратный вызов, который был назначен ранее. Вот почему есть хороший метод, который "регистрирует указанного слушателя в EventTarget, для которого он вызывается" , как говорят в MDN . Вы можете зарегистрировать столько слушателей, сколько хотите на одном мероприятии.

Позвольте мне немного переписать ответ.

function testImage(url) {
    var tester = new Image();
    tester.addEventListener('load', imageFound);
    tester.addEventListener('error', imageNotFound);
    tester.src = url;
}

function imageFound() {
    alert('That image is found and loaded');
}

function imageNotFound() {
    alert('That image was not found.');
}

testImage("http://foo.com/bar.jpg");

Поскольку процесс загрузки внешних ресурсов является асинхронным, было бы еще лучше использовать современный JavaScript с обещаниями, такими как следующие.

function testImage(url) {

    // Define the promise
    const imgPromise = new Promise(function imgPromise(resolve, reject) {

        // Create the image
        const imgElement = new Image();

        // When image is loaded, resolve the promise
        imgElement.addEventListener('load', function imgOnLoad() {
            resolve(this);
        });

        // When there's an error during load, reject the promise
        imgElement.addEventListener('error', function imgOnError() {
            reject();
        })

        // Assign URL
        imgElement.src = url;

    });

    return imgPromise;
}

testImage("http://foo.com/bar.jpg").then(

    function fulfilled(img) {
        console.log('That image is found and loaded', img);
    },

    function rejected() {
        console.log('That image was not found');
    }

);
15 голосов
/ 16 февраля 2018

Это:

<img onerror="this.src='/images/image.png'" src="...">
4 голосов
/ 03 ноября 2017
/**
 * Tests image load.
 * @param {String} url
 * @returns {Promise}
 */
function testImageUrl(url) {
  return new Promise(function(resolve, reject) {
    var image = new Image();
    image.addEventListener('load', resolve);
    image.addEventListener('error', reject);
    image.src = url;
  });
}

return testImageUrl(imageUrl).then(function imageLoaded(e) {
  return imageUrl;
})
.catch(function imageFailed(e) {
  return defaultImageUrl;
});
3 голосов
/ 16 апреля 2018

jQuery + CSS для img

С jQuery это работает для меня:

$('img').error(function() {
    $(this).attr('src', '/no-img.png').addClass('no-img');
});

И я могу использовать эту картинку повсюду на моем сайте, независимо от ее размера, со следующимиСвойство CSS3:

img.no-img {
    object-fit: cover;
    object-position: 50% 50%;
}

СОВЕТ 1: используйте квадратное изображение размером не менее 800 x 800 пикселей.

СОВЕТ 2: для использования с портрет людей , используйте object-position: 20% 50%;

CSS только для background-img

Для отсутствующих фоновых изображений я также добавил следующее в каждое объявление background-image:

background-image: url('path-to-image.png'), url('no-img.png');

ПРИМЕЧАНИЕ: не работает с прозрачными изображениями.

Сторона сервера Apache

Другое решение состоит в обнаружении отсутствующего изображения с помощью Apache перед отправкойв браузер и замените его содержимым по умолчанию no-img.png.

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} /images/.*\.(gif|jpg|jpeg|png)$
RewriteRule .* /images/no-img.png [L,R=307]
3 голосов
/ 22 марта 2012

Вот функция, которую я написал для другого ответа: Javascript Image Url Verify . Я не знаю, является ли это именно тем, что вам нужно, но он использует различные методы, которые вы бы использовали, включая обработчики для onload, onerror, onabort и общее время ожидания.

Поскольку загрузка изображения выполняется асинхронно, вы вызываете эту функцию с вашим изображением, а затем она вызывает ваш обратный вызов через некоторое время с результатом.

0 голосов
/ 22 марта 2012

как показано ниже:

var img = new Image(); 
img.src = imgUrl; 

if (!img.complete) {

//has picture
}
else //not{ 

}
...