¿Hay alguna forma de representar una imagen predeterminada en una <img>
etiqueta HTML , en caso de que el src
atributo sea inválido (usando solo HTML)? Si no, ¿cuál sería su forma ligera de solucionarlo?
¿Hay alguna forma de representar una imagen predeterminada en una <img>
etiqueta HTML , en caso de que el src
atributo sea inválido (usando solo HTML)? Si no, ¿cuál sería su forma ligera de solucionarlo?
Respuestas:
Solicitaste una solución solo 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 la primera imagen no existe, se mostrará el respaldo (los sprites utilizados en este sitio web *). Y si está utilizando un navegador realmente antiguo que no es compatible object
, ignorará esa etiqueta y la usará img
. Ver el sitio web de caniuse para compatibilidad. Este elemento es ampliamente compatible con todos los navegadores de IE6 +.
* A menos que la URL de la imagen haya cambiado (nuevamente), en cuyo caso probablemente verá el texto alternativo.
X-Frame-Options
establecido en SAMEORIGIN
una configuración más permisiva.
Esto funciona bien para mi. Tal vez quieras usar JQuery para enganchar el evento.
<img src="foo.jpg" onerror="if (this.src != 'error.jpg') this.src = 'error.jpg';">
Actualizado con jacquargs error guard
Actualizado: solución única de CSS
Recientemente vi a Vitaly Friedman demostrar una gran solución de CSS que no conocía. La idea es aplicar la content
propiedad a la imagen rota. Normalmente :after
o :before
no se aplican a las imágenes, pero cuando están rotas, se aplican.
<img src="nothere.jpg">
<style>
img:before {
content: ' ';
display: block;
position: absolute;
height: 50px;
width: 50px;
background-image: url(ishere.jpg);
</style>
Demostración: https://jsfiddle.net/uz2gmh2k/2/
Como muestra el violín, la imagen rota en sí no se elimina, pero esto probablemente resolverá el problema en la mayoría de los casos sin JS ni trozos de CSS. Si necesita aplicar diferentes imágenes en diferentes ubicaciones, simplemente diferencie con una clase:.my-special-case img:before { ...
onerror="this.src='error.jpg';this.onerror='';"
Encontré esta solución en Spring in Action 3rd Ed.
<img src="../resources/images/Image1.jpg" onerror="this.src='../resources/images/none.jpg'" />
Actualización:
Esta no es una solución solo HTML ... onerror
es javascript
<img style="background-image: url(image1), url(image2);"></img>
Use una imagen de fondo que le permita agregar varias imágenes. Mi caso: image1 es la imagen principal, esto se obtendrá de algún lugar (el navegador está haciendo una solicitud) image2 es una imagen local predeterminada para mostrar mientras se carga image1. Si image1 devuelve algún tipo de error, el usuario no verá ningún cambio y esto estará limpio para la experiencia del usuario
<style type="text/css">
img {
background-image: url('/images/default.png')
}
</style>
Asegúrese de ingresar las dimensiones de la imagen y si desea que la imagen se muestre en mosaico o no.
No creo que sea posible usando solo HTML. Sin embargo, usar JavaScript debería ser factible. Bassicly hacemos un bucle sobre cada imagen, verificamos si está completa y si es natural El ancho es cero, entonces eso significa que no se encuentra. Aquí está el 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;
}
}
}
Úselo así:
window.onload = function() {
fixBrokenImages('example.com/image.png');
}
Probado en Chrome y Firefox
Si está utilizando Angular / jQuery, esto podría ayudar ...
<img ng-src="{{item.url}}" altSrc="{{item.alt_url}}" onerror="this.src = $(this).attr('altSrc')">
Explicación
Suponiendo que item
tiene una propiedad url
que podría ser nula, cuando lo sea, la imagen se mostrará rota. Eso desencadena la ejecución de la onerror
expresión de atributo, como se describió anteriormente. src
Debe anular el atributo como se describe anteriormente, pero necesitará jQuery para acceder a su altSrc. No se pudo hacer que funcione con JavaScript de vainilla.
Puede parecer un poco hacky pero salvó el día en mi proyecto.
un elemento img simple no es muy flexible, así que lo combiné con un elemento de imagen. de esta manera no se necesita CSS. cuando se produce un error, todos los srcset se configuran en la versión alternativa. una imagen de enlace rota no se muestra. no carga versiones de imagen innecesarias. el elemento de imagen admite un diseño receptivo y múltiples fallos para tipos que no son compatibles con el 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'">
Solución simple y ordenada que implica algunas buenas respuestas y comentarios.
<img src="foo.jpg" onerror="this.src='error.jpg';this.onerror='';">
Incluso resuelve el riesgo de bucle infinito.
Trabajó para mi.
Una solución solo HTML, donde el único requisito es que conozca el tamaño de la imagen que está insertando. No funcionará para imágenes transparentes, ya que se utiliza background-image
como relleno.
Podemos usar background-image
con éxito para vincular la imagen que aparece si falta la imagen dada. Entonces, el único problema es la imagen de icono rota: podemos eliminarla insertando un carácter vacío muy grande, empujando así el contenido fuera de la pantalla 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
Una solución solo para CSS (solo 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
No hay forma de estar seguro de la gran cantidad de clientes (navegadores) que intentarán ver su página. Un aspecto a tener en cuenta es que los clientes de correo electrónico son navegadores web de facto y no pueden manejar tales trucos ...
Como tal, TAMBIÉN debe incluir un texto alternativo con un ANCHO y ALTURA POR DEFECTO, como este. Esta es una solución HTML pura.
alt="NO IMAGE" width="800" height="350"
Entonces, la otra buena respuesta se modificaría ligeramente de la siguiente manera:
<img src="foo.jpg" onerror="if (this.src != 'error.jpg') this.src = 'error.jpg';" alt="NO IMAGE" width="800" height="350">
Tuve problemas con la etiqueta de objeto en Chrome, pero imagino que esto también se aplicaría a eso.
Puede diseñar aún más el alt / text para que sea MUY GRANDE ...
Entonces mi respuesta es usar Javascript con una buena alternativa de texto / alt.
También encontré esto interesante: cómo diseñar el atributo alt de una imagen
Una versión modulable con JQuery , agregue esto al final de su archivo:
<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>
y en tu img
etiqueta:
<img src="..." data-src-error="..." />
La solución anterior está incompleta , se perdió el atributo src
.
this.src
y this.attribute('src')
NO son lo mismo, el primero contiene la referencia completa a la imagen, por ejemplo http://my.host/error.jpg
, pero el atributo solo mantiene el valor original,error.jpg
Solución correcta
<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
en Chrome 43.
Si está utilizando Angular 1.x, puede incluir una directiva que le permitirá recurrir a cualquier cantidad de imágenes. El atributo de respaldo admite una única url, múltiples urls dentro de una matriz o una expresión angular utilizando datos de alcance:
<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" />
Agregue una nueva directiva alternativa a su módulo de aplicación 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);
});
}
};
}])
Recientemente tuve que construir un sistema alternativo que incluyera cualquier cantidad de imágenes alternativas. Así es como lo hice usando una simple función de JavaScript.
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;
}
Siento que es una forma bastante ligera de manejar muchas imágenes de respaldo.
Para cualquier imagen, solo use este código javascript:
if (ptImage.naturalWidth == 0)
ptImage.src = '../../../../icons/blank.png';
donde ptImage
es una <img>
dirección de etiqueta obtenida por document.getElementById()
.
Google lanzó esta página a las palabras clave "Image Fallback html", pero debido a que nada de lo anterior me ayudó, y estaba buscando un "soporte de respaldo svg para IE por debajo de 9", seguí buscando y esto es lo que encontré:
<img src="base-image.svg" alt="picture" />
<!--[if (lte IE 8)|(!IE)]><image src="fallback-image.png" alt="picture" /><![endif]-->
Puede estar fuera de tema, pero resolvió mi propio problema y podría ayudar a alguien más también.
Además de la brillante respuesta de Patrick , para aquellos de ustedes que buscan una solución angular js multiplataforma, aquí están:
<object type="image/png" data-ng-attr-data="{{ url || 'data:' }}">
<!-- any html as a fallback -->
</object>
Aquí hay un momento en el que estaba jugando tratando de encontrar la solución correcta: http://plnkr.co/edit/nL6FQ6kMK33NJeW8DVDY?p=preview
Si ha creado un proyecto web dinámico y ha colocado la imagen requerida en WebContent, puede acceder a la imagen utilizando el código mencionado a continuación en Spring MVC:
<img src="Refresh.png" alt="Refresh" height="50" width="50">
También puede crear una carpeta llamada img y colocar la imagen dentro de la carpeta img y colocar esa carpeta img dentro de WebContent, luego puede acceder a la imagen utilizando el código mencionado a continuación:
<img src="img/Refresh.png" alt="Refresh" height="50" width="50">
¡¡Bien!! Encontré esta manera conveniente, verifique que el atributo de altura de la imagen sea 0, luego puede sobrescribir el atributo src con la imagen predeterminada: https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/ Imagen
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');
}