Existe alguma maneira de renderizar uma imagem padrão em uma <img>
tag HTML , caso o src
atributo seja inválido (usando apenas HTML)? Caso contrário, qual seria sua maneira mais leve de contornar isso?
Existe alguma maneira de renderizar uma imagem padrão em uma <img>
tag HTML , caso o src
atributo seja inválido (usando apenas HTML)? Caso contrário, qual seria sua maneira mais leve de contornar isso?
Respostas:
Você solicitou uma solução somente HTML ...
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<title>Object Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p>
<object data="http://stackoverflow.com/does-not-exist.png" type="image/png">
<img src="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.
X-Frame-Options
definida como SAMEORIGIN
ou uma configuração mais permissiva.
Isto funciona bem para mim. Talvez você queira usar o JQuery para conectar o evento.
<img src="foo.jpg" onerror="if (this.src != 'error.jpg') this.src = 'error.jpg';">
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.
<img src="nothere.jpg">
<style>
img:before {
content: ' ';
display: block;
position: absolute;
height: 50px;
width: 50px;
background-image: url(ishere.jpg);
</style>
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 { ...
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
é javascript
<img style="background-image: url(image1), url(image2);"></img>
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
<style type="text/css">
img {
background-image: url('/images/default.png')
}
</style>
Certifique-se de inserir as dimensões da imagem e se deseja que a imagem seja ladrilhada ou não.
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;
}
}
}
Use-o assim:
window.onload = function() {
fixBrokenImages('example.com/image.png');
}
Testado no Chrome e Firefox
Se você estiver usando Angular / jQuery, isso pode ajudar ...
<img ng-src="{{item.url}}" altSrc="{{item.alt_url}}" onerror="this.src = $(this).attr('altSrc')">
Explicação
Supondo que item
tenha uma propriedade url
que possa ser nula, quando estiver, a imagem aparecerá como quebrada. Isso aciona a execução da onerror
expressão de atributo, conforme descrito acima. Você precisa substituir o src
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.
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.
<picture>
<source id="s1" srcset="image1_not_supported_by_browser.webp" type="image/webp">
<source id="s2" srcset="image2_broken_link.png" type="image/png">
<img src="image3_fallback.jpg" alt="" onerror="this.onerror=null;document.getElementById('s1').srcset=document.getElementById('s2').srcset=this.src;">
</picture>
angular2:
<img src="{{foo.url}}" onerror="this.src='path/to/altimg.png'">
Solução simples e limpa, envolvendo boas respostas e comentários.
<img src="foo.jpg" onerror="this.src='error.jpg';this.onerror='';">
Ele até resolve o risco de loop infinito.
Trabalhou para mim.
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 de img
.
img {
background-image: url("http://placehold.it/200x200");
overflow: hidden;
}
img:before {
content: " ";
font-size: 1000px;
}
This image is missing:
<img src="a.jpg" style="width: 200px; height: 200px"/><br/>
And is displaying the placeholder
Uma solução somente CSS (apenas Webkit)
img:before {
content: " ";
font-size: 1000px;
background-image: url("http://placehold.it/200x200");
display: block;
width: 200px;
height: 200px;
position: relative;
z-index: 0;
margin-bottom: -16px;
}
This image is there:
<img src="http://placehold.it/100x100"/><br/>
This image is missing:
<img src="a.jpg"/><br/>
And is displaying the placeholder
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:
<img src="foo.jpg" onerror="if (this.src != 'error.jpg') this.src = 'error.jpg';" alt="NO IMAGE" width="800" height="350">
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
Uma versão modulável com JQuery , adicione isso no final do seu arquivo:
<script>
$(function() {
$('img[data-src-error]').error(function() {
var o = $(this);
var errorSrc = o.attr('data-src-error');
if (o.attr('src') != errorSrc) {
o.attr('src', errorSrc);
}
});
});
</script>
e na sua img
tag:
<img src="..." data-src-error="..." />
A solução acima está incompleta , perdeu o atributo src
.
this.src
e 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
Solução correta
<img src="foo.jpg" onerror="if (this.src != 'error.jpg' && this.attribute('src') != 'error.jpg') this.src = 'error.jpg';" />
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:
<img ng-src="myFirstImage.png" fallback="'fallback1.png'" />
<img ng-src="myFirstImage.png" fallback="['fallback1.png', 'fallback2.png']" />
<img ng-src="myFirstImage.png" fallback="myData.arrayOfImagesToFallbackTo" />
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;
} else if (typeof expressionResult === 'object' && expressionResult instanceof Array) {
// 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);
});
}
};
}])
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
<img src="some_image.tiff"
onerror="fallBackImg(this);"
data-fallIndex="1"
data-fallback1="some_image.png"
data-fallback2="some_image.jpg">
Javascript
function fallBackImg(elem){
elem.onerror = null;
let index = +elem.dataset.fallIndex;
elem.src = elem.dataset[`fallback${index}`];
index++;
elem.dataset.fallbackindex = index;
}
Sinto que é uma maneira bastante leve de lidar com muitas imagens de fallback.
Para qualquer imagem, basta usar este código javascript:
if (ptImage.naturalWidth == 0)
ptImage.src = '../../../../icons/blank.png';
onde ptImage
é um <img>
endereço de tag obtido por document.getElementById()
.
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:
<img src="base-image.svg" alt="picture" />
<!--[if (lte IE 8)|(!IE)]><image src="fallback-image.png" alt="picture" /><![endif]-->
Pode ser fora do tópico, mas resolveu meu próprio problema e também pode ajudar outra pessoa.
Além da brilhante resposta de Patrick , para aqueles que procuram uma solução js angular de plataforma cruzada, aqui está:
<object type="image/png" data-ng-attr-data="{{ url || 'data:' }}">
<!-- any html as a fallback -->
</object>
Aqui está uma brincadeira em que eu estava jogando, tentando encontrar a solução certa: http://plnkr.co/edit/nL6FQ6kMK33NJeW8DVDY?p=preview
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:
<img src="Refresh.png" alt="Refresh" height="50" width="50">
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:
<img src="img/Refresh.png" alt="Refresh" height="50" width="50">
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
image.setAttribute('src','../icons/<some_image>.png');
//check the height attribute.. if image is available then by default it will
//be 100 else 0
if(image.height == 0){
image.setAttribute('src','../icons/default.png');
}