Como ocultar silenciosamente o ícone “Imagem não encontrada” quando a imagem fonte src não for encontrada

91

Você sabe como ocultar o ícone clássico “Imagem não encontrada” de uma página HTML renderizada quando um arquivo de imagem não é encontrado?

Qualquer método de trabalho usando JavaScript / jQuery / CSS?

systempuntoout
fonte
A resposta de Andy está correta, no entanto, você pode usar style.vsibility em vez disso. Se você definir a visibilidade, o elemento ainda mantém seu espaço no documento, portanto, nenhum movimento engraçado do documento.
Christian
Eu não vejo o ponto. Você simplesmente não deve tentar alcançar nenhum recurso existente do seu código html. Usar javascript para esconder recursos mal negociados parece ser uma solução feia para mim.
Boris Delormas
1
@Kaaviar Você está perdendo o ponto. Há muitas imagens com links quebrados aqui no Stack Overflow devido ao fato de que as imagens podem estar disponíveis no momento da postagem, mas indisponíveis alguns meses depois. Essas imagens são escondidas silenciosa e suavemente.
systempuntoout
1
@systempuntoout: Não sei por que os dois são tratados de maneira diferente. Testei uma imagem quebrada no Firefox e no Chrome, ela não aparece no Firefox, mas aparece quebrada no Chrome. É claro que isso é algo que o Firefox está decidindo por conta própria, já que não parece que nenhum estilo o esteja afetando. Aliás, ótimo trabalho no StackPrinter.
Andy E
2
@systempuntoout: descobri um pouco mais de informações sobre como o Firefox funciona com isso. Veja um fiddle atualizado e a [pseudo-classe proprietária :-moz-broken] ( developer.mozilla.org/en/CSS/:-moz-broken ). Eu estava pensando comigo mesmo antes que uma pseudo aula seria útil para estilizar imagens quebradas.
Andy E

Respostas:

102

Você pode usar o onerrorevento em JavaScript para agir quando uma imagem falha ao carregar:

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

No jQuery (já que você perguntou):

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

Ou para todas as imagens:

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

Você deve usar em visibility: hiddenvez de .hide()se esconder as imagens pode alterar o layout. Muitos sites na web usam uma imagem padrão "sem imagem", apontando o srcatributo para essa imagem quando o local da imagem especificado não está disponível.

Andy E
fonte
1
andy - qual seria a solução 'global' para aplicar a TODAS as imagens ?? estou pensando que seria fácil se eles estivessem todos no mesmo div - apenas me perguntei sobre TODAS as imagens no documento ...
Jim Tollan
@jAndy: Eu tinha quase certeza que sim, mas seu comentário me fez verificar novamente. Um rápido Google retornou esta página w3schools (desculpe David, se você está lendo isso) indicando suporte para vários navegadores.
Andy E
2
@jim: Se estiver usando jQuery, você pode aplicar o evento a todas as imagens. basta usar o seletor de tag, por exemplo $("img").error(function () { /*...*/ });.
Andy E
@Andy E: parece bom, +1. a próxima questão interessante seria, " error" é limitado com live()ou delegate().
jAndy
3
visibilityseria melhor, pois displaypode quebrar o layout.
gblazex
114
<img onerror='this.style.display = "none"'>
Gary Willoughby
fonte
Infelizmente, não posso usar essa solução porque o conteúdo html é baixado de um site de terceiros via Json e não consigo editá-lo. Obrigado mesmo assim.
systempuntoout
9
Incrível, exatamente o que eu precisava. Simples e desobstrutivo, ele se encaixa em um modelo!
Máx.
Embora já seja bastante antigo, isso é ótimo! Existe uma maneira de ocultar as marcas <a> ao redor da minha imagem agora oculta também?
SJDS de
9

Modifiquei ligeiramente a solução sugerida por Gary Willoughby, porque mostra brevemente o ícone da imagem quebrada. Minha solução:

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

Na minha solução, a imagem está inicialmente oculta e é exibida apenas quando é carregada com sucesso. Isso tem uma desvantagem: os usuários não verão imagens carregadas pela metade. E se o usuário desabilitou JS, então ele nunca verá nenhuma imagem

Faixa
fonte
1
... e os usuários não verão nada, se o javascript estiver desabilitado!
início de
4
@yckart Bem, se os usuários tiverem o javascript desabilitado, a maioria dos aplicativos da web úteis não funcionarão de qualquer maneira ...
awe
<img src="..." onerror="this.style.display = 'none'"/>pode funcionar melhor para os casos de navegador meio carregado e não-js?
6

Para ocultar todos os erros de imagem, basta adicionar este JavaScript na parte inferior da página (antes da tag de fechamento do corpo):

(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
fonte
Esta é a minha abordagem preferida porque praticamente garante que os eventos onerror sejam vinculados antes que as imagens tenham sido erradas e você não precisa adicionar atributos onerror a cada tag de imagem. Certifique-se de colocar este código após todas as suas tags de imagem, mas antes de qualquer outro javascript que esteja em <body>, caso contrário, um bloqueio de carregamento de JS externo pode causar a execução após um erro de imagem.
galatas de
Este funciona para mim, junto com o conselho de galatas, preciso ter este JS executado antes de qualquer coisa que possa atrasá-lo.
Adamz
Isso responde à pergunta original, mas é um processo unilateral. Para tornar as imagens que carregam posteriormente visíveis novamente, adicione um evento onload também. allimgs [i] .onload = function () {this.style.visibility = "visible"; };
TRT 1968
5

Pode ser um pouco tarde para responder, mas aqui está minha tentativa. Quando enfrentei o mesmo problema, resolvi usando um div do tamanho da imagem e definindo a imagem de fundo para este div. Se a imagem não for encontrada, o div é apresentado como transparente, então tudo é feito silenciosamente, sem código java-script.

Adway Lele
fonte
4

Fazendo uma pesquisa rápida sobre a resposta de Andy E , não é possível live()vincular error.

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

Então você tem que ir como

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

vinculando diretamente o error event handlerna criação de um novo elemento.

Andy
fonte
2
+1, a razão para isso é que o evento onerror DOM não borbulha. ao vivo e delegar trabalho colocando o manipulador de eventos mais acima na hierarquia do DOM e capturando o evento conforme ele surge. Claro, os desenvolvedores do jQuery resolveram isso para alguns eventos como foco e desfoque
Andy E
@Andy E: Eba, eles já contornaram isso, pode não ser a pior das ideias para fazer algo semelhante error. Parece um nice to havepara mim.
jAndy
3

Eu descobri um método bacana para fazer exatamente isso, enquanto ainda ng-srcestou funcional ao usar a diretiva em Angular.js e assim ...

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

é basicamente um GIF transparente mais curto (como visto 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% 20smallest% 20transparent% 20pixel.html )

é claro que esse gif pode ser mantido dentro de alguma variável global para não bagunçar os modelos.

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

E use

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

etc.

Jacek Głodek
fonte
0

Basta usar css simples

.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;
}
Owais Bin Rizwan
fonte