Как тихо скрыть значок «Изображение не найдено», если исходное изображение src не найдено

91

Вы знаете, как скрыть классический значок «Изображение не найдено» на обработанной HTML-странице, когда файл изображения не найден?

Любой метод работы с использованием JavaScript / jQuery / CSS?

systempuntoout
источник
Ответ Энди верен, однако вместо этого вы можете использовать style.vsibility. Если вы установите видимость, элемент по-прежнему сохраняет свое пространство в документе, поэтому никаких забавных движений документа.
Christian
Я не вижу в этом смысла. Вы просто не должны пытаться получить доступ к существующим ресурсам из вашего html-кода. Использование javascript для сокрытия недобросовестных ресурсов кажется мне уродливым решением.
Boris Delormas,
1
@Kaaviar Вы упускаете суть. В Stack Overflow есть много изображений с горячими ссылками, которые не работают из-за того, что изображения могут быть доступны на момент публикации, но недоступны через несколько месяцев. Эти образы тихо и аккуратно скрыты.
systempuntoout
1
@systempuntoout: я не уверен, почему к ним относятся по-разному. Я тестировал сломанное изображение в Firefox и Chrome, оно не отображается в Firefox, но отображается как сломанное в Chrome. Понятно, что это то, что Firefox решает сам по себе, поскольку не похоже, что какие-либо стили влияют на это. Кстати, отличная работа над StackPrinter.
Andy E
2
@systempuntoout: Я узнал немного больше о том, как Firefox работает с этим. См. Обновленную скрипку и [собственный псевдокласс, :-moz-broken] ( developer.mozilla.org/en/CSS/:-moz-broken ). Раньше я просто думал про себя, что псевдокласс был бы полезен для стилизации битых изображений.
Andy E

Ответы:

102

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

var img = document.getElementById("myImg");
img.onerror = function () { 
    this.style.display = "none";
}

В jQuery (раз уж вы просили):

$("#myImg").error(function () { 
    $(this).hide(); 
});

Или для всех изображений:

$("img").error(function () { 
    $(this).hide();
    // or $(this).css({visibility:"hidden"}); 
});

Вы должны использовать visibility: hiddenвместо этого, .hide()если скрытие изображений может изменить макет. Многие сайты в Интернете вместо этого используют изображение по умолчанию «без изображения», указывая srcатрибут на это изображение, когда указанное расположение изображения недоступно.

Энди Э
источник
1
Энди - какое «глобальное» решение можно применить ко ВСЕМ изображениям ?? Я думаю, было бы достаточно просто, если бы все они были в одном блоке - просто интересно, ВСЕ изображения в документе ...
Джим Толлан
@jAndy: Я был в этом уверен, но ваш комментарий заставил меня перепроверить. Google быстро вернул эту страницу w3schools (извините, Дэвид, если вы это читаете), указывая на поддержку кроссбраузерности.
Andy E
2
@jim: Если вы используете jQuery, вы можете применить событие ко всем изображениям. просто используйте селектор тегов, например $("img").error(function () { /*...*/ });.
Andy E
@ Энди Э: звучит хорошо, +1. следующий интересный вопрос: " error" можно ли связать с помощью live()или delegate().
jAndy
3
visibilityбудет лучше, т.к. displayможет нарушить макет.
gblazex
114
<img onerror='this.style.display = "none"'>
Гэри Уиллоуби
источник
К сожалению, я не могу использовать это решение, потому что html-контент загружается со стороннего веб-сайта через Json, и я не могу его редактировать. Спасибо, в любом случае.
systempuntoout
9
Отлично, именно то, что мне нужно. Простой и удобный, он умещается в шаблоне!
Макс
Хотя уже довольно старый, это здорово! Есть ли способ скрыть теги <a>, окружающие мое теперь скрытое изображение?
SJDS
9

Я немного изменил решение, предложенное Гэри Уиллоуби, потому что оно на короткое время показывает значок сломанного изображения. Мое решение:

    <img src="..." style="display: none" onload="this.style.display=''">

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

Кушак
источник
1
... и пользователи ничего не увидят, если javascript отключен!
yckart
4
@yckart Что ж, если у пользователей отключен javascript, большинство полезных веб-приложений все равно не будут работать ...
трепет
<img src="..." onerror="this.style.display = 'none'"/>может работать лучше для случаев с неполной загрузкой и без js-браузера?
6

Чтобы скрыть каждую ошибку изображения, просто добавьте этот код JavaScript внизу страницы (непосредственно перед закрывающим тегом body):

(function() {
    var allimgs = document.images;
    for (var i = 0; i < allimgs.length; i++) {
        allimgs[i].onerror = function() {
            this.style.visibility = "hidden"; // Other elements aren't affected. 
        }
    }
})();
Q_Mlilo
источник
Это мой предпочтительный подход, потому что он в значительной степени гарантирует, что события onerror будут привязаны до того, как изображения будут ошибочными, и вам не нужно добавлять атрибуты onerror к каждому тегу изображения. Обязательно поместите этот код после всех ваших тегов изображений, но перед любым другим JavaScript, который находится в <body>, иначе блокирующая внешняя загрузка JS может вызвать выполнение после ошибки изображения.
Galatians
Это работает для меня, наряду с советами от galatians, необходимо выполнить этот JS до того, как что-либо может задержать его.
Adamz
Это отвечает на исходный вопрос, но это односторонний процесс. Чтобы изображения, которые впоследствии загружаются, снова стали видимыми, добавьте также событие onload. allimgs [я] .onload = функция () {this.style.visibility = "видимый"; };
TRT 1968,
5

Возможно, ответить немного поздно, но вот моя попытка. Когда я столкнулся с той же проблемой, я исправил ее, используя div с размером изображения и установив background-image для этого div. Если изображение не найдено, div становится прозрачным, поэтому все это делается тихо, без кода java-скрипта.

Эдвей Леле
источник
4

Проведя быстрое исследование ответа Энди Э , невозможно live()связать его error.

// won't work (chrome 5)
$('img').live('error', function(){
     $(this).css('visibility', 'hidden');
});

Так что тебе нужно идти как

$('<img/>', {
  src:    'http://www.notarget.com/fake.jpg',
  error:  function(e){
    $(this).css('visibility', 'hidden');
  }
}).appendTo(document.body);

прямая привязка к error event handlerсозданию нового элемента.

Дженди
источник
2
+1, причина в том, что событие DOM onerror не всплывает . live и делегируйте работу, разместив обработчик событий выше по иерархии DOM и фиксируя событие по мере его всплытия. Конечно, разработчики jQuery работали над этим для некоторых событий, таких как фокус и размытие
Энди Э
@Andy E: Ура, они уже обошли эту проблему, возможно, это не самая плохая идея, для которой можно сделать то же самое error. Звучит как nice to haveдля меня.
jAndy
3

Я нашел отличный способ сделать именно это, оставаясь при этом работоспособным при использовании ng-srcдирективы в Angular.js и т.п.

<img
  ng-src="{{myCtrl.myImageUrlThatWillDynamicallyChange}}" 
  onerror="this.src='data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='"
  />

это в основном самый короткий прозрачный GIF (как показано http://proger.i-forge.net/%D0%9A%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82% D0% B5% D1% 80 / [20121112]% 20The% 20smaltest% 20transparent% 20pixel.html )

конечно, этот gif можно сохранить внутри какой-то глобальной переменной, чтобы он не испортил шаблоны.

<script>
  window.fallbackGif = "..."
</script>

и использовать

<img
  ng-src="{{myCtrl.myImageUrlThatWillDynamicallyChange}}" 
  onerror="this.src=fallbackGif"
  />

и т.п.

Яцек Глодек
источник
0

Просто используйте простой CSS

.AdminImageHolder {
display: inline-block;
min-width: 100px;
max-width: 100px;
min-height: 100px;
max-height: 100px;
background: url(img/100x100.png) no-repeat;
border: 1px solid #ccc;
}
Овайс Бин Ризван
источник