Introduzindo uma imagem padrão, caso o atributo src de um html <img> não seja válido?
268
Existe alguma maneira de renderizar uma imagem padrão em uma <img>tag HTML , caso o srcatributo seja inválido (usando apenas HTML)? Caso contrário, qual seria sua maneira mais leve de contornar isso?
HTML não tem substituto para imagens quebradas. Você precisaria usar o JavaScript para encontrar imagens quebradas e alterar o atributo src.
Blixt
2
@Blixt - O que se seu cliente for MS Outlook ou o leitor EMAIL someother e você não tem Javascript, ea opção objeto não trabalho ... Eu presumo que a única solução é alt / text
Xofo
Respostas:
319
Você solicitou uma solução somente HTML ...
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd"><htmllang="en"><head><title>Object Test</title><metahttp-equiv="Content-Type"content="text/html; charset=utf-8"></head><body><p><objectdata="http://stackoverflow.com/does-not-exist.png"type="image/png"><imgsrc="https://cdn.sstatic.net/Img/unified/sprites.svg?v=e5e58ae7df45"alt="Stack Overflow logo and icons and such"></object></p></body></html>
Como a primeira imagem não existe, o fallback (os sprites usados neste site *) será exibido. E se você estiver usando um navegador realmente antigo que não suporta object, ele ignorará essa tag e a usará img. Consulte o site da caniuse para obter compatibilidade. Este elemento é amplamente suportado por todos os navegadores do IE6 +.
* A menos que o URL da imagem seja alterado (novamente), nesse caso, você provavelmente verá o texto alternativo.
Funcionou para mim no IE8 depois de inserir o DTD para HTML 4.01.
22320 Patrick McElhaney
Isso não funciona se a imagem inexistente tiver sido X-Frame-Optionsdefinida como SAMEORIGINou uma configuração mais permissiva.
Attila O.
Ele funciona, mas se o link em object.data não é confiável, ele pode carregar todo o tipo de coisas ...
Michael_Scharf
1
O elemento 'img' não pode ser aninhado dentro do elemento 'objeto'.
Matheus Miranda
2
@ Matheus Claro que pode. No HTML4, o objeto pode conter conteúdo de fluxo (quase tudo, inclusive img), e no HTML5 é transparente, o que significa que pode conter qualquer HTML5 válido.
Patrick McElhaney
318
Isto funciona bem para mim. Talvez você queira usar o JQuery para conectar o evento.
Atualizado: solução somente CSS
Eu vi recentemente a demonstração de Vitaly Friedman uma ótima solução CSS que eu não conhecia. A idéia é aplicar a contentpropriedade à imagem quebrada. Normalmente :afterou :beforenão se aplicam a imagens, mas quando estão quebradas, são aplicadas.
Como o violino mostra, a imagem quebrada em si não é removida, mas isso provavelmente resolverá o problema na maioria dos casos, sem JS e sem CSS. Se você precisar aplicar imagens diferentes em locais diferentes, basta diferenciar com uma classe:.my-special-case img:before { ...
Na minha opinião. Essa é a melhor resposta. Aqui estão os modos peculiares de assumir um erro ... parece bastante seguro para mim. quirksmode.org/dom/events/error.html#t01
n0nag0n
12
BTW, se error.jpg não existir, isso causa um loop infinito, porque ele continua tentando encontrar a imagem; onError é chamado novamente, não é possível encontrá-lo e tudo começa novamente.
#
30
Para evitar riscos de loop infinito, basta adicionar um teste: <img src = "foo.jpg" onerror = "if (this.src! = 'Error.jog') this.src = 'error.jpg';">
jacquarg
21
Como alternativa, você pode escrever:onerror="this.src='error.jpg';this.onerror='';"
Denilson Sá Maia
6
Onde está o jQuery nisso?
Praveen Kumar Purushothaman
64
Encontrei esta solução no Spring in Action 3rd Ed.
Isso funciona muito bem. Aqui está uma atualização com uma imagem de fallback no imgur: <img src = "a-falta-imagem.jpg" alt = "" onerror = "this.src = 'http: ///i.imgur.com/hfM1J8s.png' ">
Use a imagem de fundo que permite adicionar várias imagens. Meu caso: image1 é a imagem principal; isso será obtido em algum lugar (navegador fazendo uma solicitação) image2 é uma imagem local padrão a ser exibida enquanto a imagem1 está sendo carregada. Se a imagem1 retornar algum tipo de erro, o usuário não verá nenhuma alteração e isso ficará limpo para a experiência do usuário
A maioria dos navegadores não mostra uma imagem de 'link quebrado' quando a imagem não é encontrada ... Nesse caso, definir o plano de fundo não resolveria o problema.
Justin D.
13
Eu não acho que é possível usar apenas HTML. No entanto, usando javascript, isso deve ser possível. Em baixo, percorremos cada imagem, testamos se ela está completa e se a largura natural é zero, isso significa que ela não foi encontrada. Aqui está o código:
fixBrokenImages =function( url ){var img = document.getElementsByTagName('img');var i=0, l=img.length;for(;i<l;i++){var t = img[i];if(t.naturalWidth ===0){//this image is broken
t.src = url;}}}
Supondo que itemtenha uma propriedade urlque possa ser nula, quando estiver, a imagem aparecerá como quebrada. Isso aciona a execução da onerrorexpressão de atributo, conforme descrito acima. Você precisa substituir o srcatributo conforme descrito acima, mas precisará do jQuery para acessar seu altSrc. Não foi possível fazê-lo funcionar com JavaScript de baunilha.
Pode parecer um pouco hacky, mas salvou o dia no meu projeto.
um simples elemento img não é muito flexível, então eu o combinei com um elemento de imagem. dessa forma, nenhum CSS é necessário. quando ocorre um erro, todos os srcset são definidos para a versão de fallback. uma imagem de link quebrado não está aparecendo. ele não carrega versões de imagem desnecessárias. o elemento picture suporta design responsivo e vários fallbacks para tipos que não são suportados pelo navegador.
esse é ótimo! esteja atento ao suporte ao navegador ausente caniuse.com/#feat=picture . considere usar um polyfill ou outra solução se precisar oferecer suporte a navegadores mais antigos como o IE11.
Embora isso possa funcionar, acho que não adiciona nenhuma informação nova. A parte onerror é apenas baunilha JavaScript eo src ligação já deve ser conhecido pelos usuários angular
Chic
7
Solução simples e limpa, envolvendo boas respostas e comentários.
Não, eu também não diria que é legal. Sem mencionar que esta é provavelmente uma reformulação de outras soluções.
Script47
Funciona como um encanto! Obrigado!
Goehybrid #
1
Lifesaver. Não queria elegante, queria simples e trabalhadora. Obrigado!
Kit
7
Uma solução apenas para HTML, onde o único requisito é que você saiba o tamanho da imagem que está inserindo. Não funcionará para imagens transparentes, pois é usado background-imagecomo preenchimento.
Podemos usar background-imagecom êxito para vincular a imagem que aparece se a imagem fornecida estiver ausente. Então, o único problema é a imagem quebrada do ícone - podemos removê-la inserindo um caractere vazio muito grande, empurrando o conteúdo para fora da tela de img.
Não há como ter certeza do grande número de clientes (navegadores) que tentarão exibir sua página. Um aspecto a considerar é que os clientes de email são navegadores da web padrão e podem não lidar com tais truques de truques ...
Como tal, você também deve incluir um texto alternativo com uma LARGURA E ALTURA PADRÃO, assim. Esta é uma solução HTML pura.
alt="NO IMAGE" width="800" height="350"
Portanto, a outra boa resposta seria ligeiramente modificada da seguinte maneira:
A solução acima está incompleta , perdeu o atributo src.
this.srce this.attribute('src')NÃO são iguais, o primeiro contém a referência completa à imagem, por exemplo http://my.host/error.jpg, mas o atributo apenas mantém o valor original,error.jpg
Ao usar este código, eu vejo Uncaught TypeError: this.attribute is not a functionno Chrome 43.
John Washam
Você está usando jQuery?
mix3d
O onError está obsoleto de acordo com developer.mozilla.org/pt-BR/docs/Web/HTML/Element/img
comiventor
2
Se você estiver usando o Angular 1.x, poderá incluir uma diretiva que permita o retorno a qualquer número de imagens. O atributo fallback suporta um único URL, vários URLs dentro de uma matriz ou uma expressão angular usando dados de escopo:
Adicione uma nova diretiva de fallback ao seu módulo de aplicativo angular:
angular.module('app.services',[]).directive('fallback',['$parse',function($parse){return{restrict:'A',
link:function(scope, element, attrs){var errorCount =0;// Hook the image element error event
angular.element(element).bind('error',function(err){var expressionFunc = $parse(attrs.fallback),
expressionResult,
imageUrl;
expressionResult = expressionFunc(scope);if(typeof expressionResult ==='string'){// The expression result is a string, use it as a url
imageUrl = expressionResult;}elseif(typeof expressionResult ==='object'&& expressionResult instanceofArray){// The expression result is an array, grab an item from the array// and use that as the image url
imageUrl = expressionResult[errorCount];}// Increment the error count so we can keep track// of how many images we have tried
errorCount++;
angular.element(element).attr('src', imageUrl);});}};}])
Idéia legal! Uma matriz off imagens de fallback é uma boa implementação
Z. Khullah
1
Recentemente, tive que criar um sistema de fallback que incluísse qualquer número de imagens de fallback. Aqui está como eu fiz isso usando uma função JavaScript simples.
O Google lançou esta página com as palavras-chave "image fallback html", mas como as opções acima não me ajudaram, e eu estava procurando por um "suporte de fallback svg para o IE abaixo de 9", continuei pesquisando e foi isso que descobri:
Se você criou um projeto dinâmico da Web e colocou a imagem necessária no WebContent, pode acessar a imagem usando o código abaixo mencionado no Spring MVC:
Você também pode criar uma pasta chamada img e colocar a imagem dentro da pasta img e colocar a pasta img dentro do WebContent para acessar a imagem usando o código abaixo mencionado:
image.setAttribute('src','../icons/<some_image>.png');//check the height attribute.. if image is available then by default it will //be 100 else 0if(image.height ==0){
image.setAttribute('src','../icons/default.png');}
Respostas:
Você solicitou uma solução somente HTML ...
Como a primeira imagem não existe, o fallback (os sprites usados neste site *) será exibido. E se você estiver usando um navegador realmente antigo que não suporta
object
, ele ignorará essa tag e a usaráimg
. Consulte o site da caniuse para obter compatibilidade. Este elemento é amplamente suportado por todos os navegadores do IE6 +.* A menos que o URL da imagem seja alterado (novamente), nesse caso, você provavelmente verá o texto alternativo.
fonte
X-Frame-Options
definida comoSAMEORIGIN
ou uma configuração mais permissiva.Isto funciona bem para mim. Talvez você queira usar o JQuery para conectar o evento.
Atualizado com o protetor de erro jacquargs
Atualizado: solução somente CSS Eu vi recentemente a demonstração de Vitaly Friedman uma ótima solução CSS que eu não conhecia. A idéia é aplicar a
content
propriedade à imagem quebrada. Normalmente:after
ou:before
não se aplicam a imagens, mas quando estão quebradas, são aplicadas.Demonstração: https://jsfiddle.net/uz2gmh2k/2/
Como o violino mostra, a imagem quebrada em si não é removida, mas isso provavelmente resolverá o problema na maioria dos casos, sem JS e sem CSS. Se você precisar aplicar imagens diferentes em locais diferentes, basta diferenciar com uma classe:
.my-special-case img:before { ...
fonte
onerror="this.src='error.jpg';this.onerror='';"
Encontrei esta solução no Spring in Action 3rd Ed.
<img src="../resources/images/Image1.jpg" onerror="this.src='../resources/images/none.jpg'" />
Atualização: Esta não é uma solução apenas para HTML ...
onerror
é javascriptfonte
Use a imagem de fundo que permite adicionar várias imagens. Meu caso: image1 é a imagem principal; isso será obtido em algum lugar (navegador fazendo uma solicitação) image2 é uma imagem local padrão a ser exibida enquanto a imagem1 está sendo carregada. Se a imagem1 retornar algum tipo de erro, o usuário não verá nenhuma alteração e isso ficará limpo para a experiência do usuário
fonte
Certifique-se de inserir as dimensões da imagem e se deseja que a imagem seja ladrilhada ou não.
fonte
Eu não acho que é possível usar apenas HTML. No entanto, usando javascript, isso deve ser possível. Em baixo, percorremos cada imagem, testamos se ela está completa e se a largura natural é zero, isso significa que ela não foi encontrada. Aqui está o código:
Use-o assim:
Testado no Chrome e Firefox
fonte
Se você estiver usando Angular / jQuery, isso pode ajudar ...
Explicação
Supondo que
item
tenha uma propriedadeurl
que possa ser nula, quando estiver, a imagem aparecerá como quebrada. Isso aciona a execução daonerror
expressão de atributo, conforme descrito acima. Você precisa substituir osrc
atributo conforme descrito acima, mas precisará do jQuery para acessar seu altSrc. Não foi possível fazê-lo funcionar com JavaScript de baunilha.Pode parecer um pouco hacky, mas salvou o dia no meu projeto.
fonte
um simples elemento img não é muito flexível, então eu o combinei com um elemento de imagem. dessa forma, nenhum CSS é necessário. quando ocorre um erro, todos os srcset são definidos para a versão de fallback. uma imagem de link quebrado não está aparecendo. ele não carrega versões de imagem desnecessárias. o elemento picture suporta design responsivo e vários fallbacks para tipos que não são suportados pelo navegador.
fonte
angular2:
fonte
Solução simples e limpa, envolvendo boas respostas e comentários.
Ele até resolve o risco de loop infinito.
Trabalhou para mim.
fonte
Uma solução apenas para HTML, onde o único requisito é que você saiba o tamanho da imagem que está inserindo. Não funcionará para imagens transparentes, pois é usado
background-image
como preenchimento.Podemos usar
background-image
com êxito para vincular a imagem que aparece se a imagem fornecida estiver ausente. Então, o único problema é a imagem quebrada do ícone - podemos removê-la inserindo um caractere vazio muito grande, empurrando o conteúdo para fora da tela deimg
.Uma solução somente CSS (apenas Webkit)
fonte
Não há como ter certeza do grande número de clientes (navegadores) que tentarão exibir sua página. Um aspecto a considerar é que os clientes de email são navegadores da web padrão e podem não lidar com tais truques de truques ...
Como tal, você também deve incluir um texto alternativo com uma LARGURA E ALTURA PADRÃO, assim. Esta é uma solução HTML pura.
Portanto, a outra boa resposta seria ligeiramente modificada da seguinte maneira:
Eu tive problemas com a tag de objeto no Chrome, mas imagino que isso se aplicaria a isso também.
Você pode estilizar ainda mais o alt / texto para ser MUITO GRANDE ...
Portanto, minha resposta é usar Javascript com um bom retorno alternativo para texto / alt.
Também achei isso interessante: Como estilizar o atributo alt de uma imagem
fonte
Uma versão modulável com JQuery , adicione isso no final do seu arquivo:
e na sua
img
tag:fonte
A solução acima está incompleta , perdeu o atributo
src
.this.src
ethis.attribute('src')
NÃO são iguais, o primeiro contém a referência completa à imagem, por exemplohttp://my.host/error.jpg
, mas o atributo apenas mantém o valor original,error.jpg
Solução correta
fonte
Uncaught TypeError: this.attribute is not a function
no Chrome 43.Se você estiver usando o Angular 1.x, poderá incluir uma diretiva que permita o retorno a qualquer número de imagens. O atributo fallback suporta um único URL, vários URLs dentro de uma matriz ou uma expressão angular usando dados de escopo:
Adicione uma nova diretiva de fallback ao seu módulo de aplicativo angular:
fonte
Recentemente, tive que criar um sistema de fallback que incluísse qualquer número de imagens de fallback. Aqui está como eu fiz isso usando uma função JavaScript simples.
HTML
Javascript
Sinto que é uma maneira bastante leve de lidar com muitas imagens de fallback.
fonte
Usando o Jquery, você poderia fazer algo assim:
fonte
Para qualquer imagem, basta usar este código javascript:
onde
ptImage
é um<img>
endereço de tag obtido pordocument.getElementById()
.fonte
O Google lançou esta página com as palavras-chave "image fallback html", mas como as opções acima não me ajudaram, e eu estava procurando por um "suporte de fallback svg para o IE abaixo de 9", continuei pesquisando e foi isso que descobri:
Pode ser fora do tópico, mas resolveu meu próprio problema e também pode ajudar outra pessoa.
fonte
Além da brilhante resposta de Patrick , para aqueles que procuram uma solução js angular de plataforma cruzada, aqui está:
Aqui está uma brincadeira em que eu estava jogando, tentando encontrar a solução certa: http://plnkr.co/edit/nL6FQ6kMK33NJeW8DVDY?p=preview
fonte
Se você criou um projeto dinâmico da Web e colocou a imagem necessária no WebContent, pode acessar a imagem usando o código abaixo mencionado no Spring MVC:
Você também pode criar uma pasta chamada img e colocar a imagem dentro da pasta img e colocar a pasta img dentro do WebContent para acessar a imagem usando o código abaixo mencionado:
fonte
Bem!! Achei isso conveniente, verifique se o atributo height da imagem é 0 e, em seguida, você pode substituir o atributo src pela imagem padrão: https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/ Imagem
fonte