¿Ingresando una imagen predeterminada en caso de que el atributo src de un html <img> no sea válido?
268
¿Hay alguna forma de representar una imagen predeterminada en una <img>etiqueta HTML , en caso de que el srcatributo sea inválido (usando solo HTML)? Si no, ¿cuál sería su forma ligera de solucionarlo?
HTML no tiene respaldo para las imágenes rotas. Debería usar JavaScript para encontrar imágenes rotas y cambiar su atributo src.
Blixt
2
@Blixt - ¿Qué sucede si su cliente es MS Outlook o algún otro lector de CORREO ELECTRÓNICO y no tiene Javascript, y la opción de objeto no funciona? Supongo que la única solución es alt / text
Xofo
Respuestas:
319
Solicitaste una solución solo 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 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.
Funcionó para mí en IE8 después de instalar DTD para HTML 4.01.
Patrick McElhaney
Esto no funciona si la imagen no existente se ha X-Frame-Optionsestablecido en SAMEORIGINuna configuración más permisiva.
Atila O.
Funciona, pero si el enlace en object.data no es confiable, puede cargar todo tipo de cosas ...
Michael_Scharf
1
El elemento 'img' no se puede anidar dentro del elemento 'objeto'.
Matheus Miranda
2
@Matheus Claro que sí. En HTML4, el objeto puede contener contenido de flujo (casi todo, incluido img), y en HTML5 es transparente, lo que significa que puede contener cualquier HTML5 válido.
Patrick McElhaney
318
Esto funciona bien para mi. Tal vez quieras usar JQuery para enganchar el evento.
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 contentpropiedad a la imagen rota. Normalmente :aftero :beforeno se aplican a las imágenes, pero cuando están rotas, se aplican.
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 { ...
Por cierto, si error.jpg no existe, esto causa un bucle infinito porque sigue tratando de encontrar la imagen, luego se llama a onError nuevamente, no puede encontrarlo y todo vuelve a comenzar.
borq
30
Para evitar el riesgo de bucle infinito, simplemente agregue una prueba: <img src = "foo.jpg" onerror = "if (this.src! = 'Error.jog') this.src = 'error.jpg';">
jacquarg
21
Alternativamente, puede escribir:onerror="this.src='error.jpg';this.onerror='';"
Denilson Sá Maia
66
¿Dónde está jQuery en esto?
Praveen Kumar Purushothaman
64
Encontré esta solución en Spring in Action 3rd Ed.
Esto funciona muy bien. Aquí hay una actualización con una imagen alternativa en imgur: <img src = "a-missing-image.jpg" alt = "" onerror = "this.src = 'http: ///i.imgur.com/hfM1J8s.png' ">
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
La mayoría de los navegadores no muestran una imagen de 'enlace roto' cuando no se encuentra la imagen ... En ese caso, establecer el fondo no resolvería el problema.
Justin D.
13
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;}}}
Suponiendo que itemtiene una propiedad urlque podría ser nula, cuando lo sea, la imagen se mostrará rota. Eso desencadena la ejecución de la onerrorexpresión de atributo, como se describió anteriormente. srcDebe 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.
este es genial! tenga en cuenta que falta el soporte del navegador caniuse.com/#feat=picture . considere usar un polyfill u otra solución si necesita admitir navegadores antiguos como IE11.
Si bien esto puede funcionar, no creo que agregue ninguna información nueva. La parte onerror es solo JavaScript vainilla y los usuarios de Angular ya deberían conocer el enlace src
Chic
7
Solución simple y ordenada que implica algunas buenas respuestas y comentarios.
En mi opinión, esto definitivamente no se ve elegante.
Script47
1
@ Script47 Está ordenada, repito ordenada
manish kumar
1
No, tampoco diría que está bien. Sin mencionar que esto es probablemente una repetición de otras soluciones.
Script47
¡Funciona de maravilla! ¡Gracias!
Goehybrid
1
Salvador de la vida. No quería elegante, quería simple y de trabajo. ¡Gracias!
Kit
7
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-imagecomo relleno.
Podemos usar background-imagecon é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.
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:
La solución anterior está incompleta , se perdió el atributo src.
this.srcy 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
Cuando uso este código, veo Uncaught TypeError: this.attribute is not a functionen Chrome 43.
John Washam
¿Estás usando jQuery?
mix3d
onError está en desuso según developer.mozilla.org/en-US/docs/Web/HTML/Element/img
comiventor
2
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:
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;}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);});}};}])
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.
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é:
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:
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:
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');}
Respuestas:
Solicitaste una solución solo 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.
fuente
X-Frame-Options
establecido enSAMEORIGIN
una configuración más permisiva.Esto funciona bien para mi. Tal vez quieras usar JQuery para enganchar el evento.
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.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 { ...
fuente
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 javascriptfuente
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
fuente
Asegúrese de ingresar las dimensiones de la imagen y si desea que la imagen se muestre en mosaico o no.
fuente
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:
Úselo así:
Probado en Chrome y Firefox
fuente
Si está utilizando Angular / jQuery, esto podría ayudar ...
Explicación
Suponiendo que
item
tiene una propiedadurl
que podría ser nula, cuando lo sea, la imagen se mostrará rota. Eso desencadena la ejecución de laonerror
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.
fuente
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.
fuente
angular2:
fuente
Solución simple y ordenada que implica algunas buenas respuestas y comentarios.
Incluso resuelve el riesgo de bucle infinito.
Trabajó para mi.
fuente
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 pantallaimg
.Una solución solo para CSS (solo Webkit)
fuente
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.
Entonces, la otra buena respuesta se modificaría ligeramente de la siguiente manera:
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
fuente
Una versión modulable con JQuery , agregue esto al final de su archivo:
y en tu
img
etiqueta:fuente
La solución anterior está incompleta , se perdió el atributo
src
.this.src
ythis.attribute('src')
NO son lo mismo, el primero contiene la referencia completa a la imagen, por ejemplohttp://my.host/error.jpg
, pero el atributo solo mantiene el valor original,error.jpg
Solución correcta
fuente
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:
Agregue una nueva directiva alternativa a su módulo de aplicación angular:
fuente
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
JavaScript
Siento que es una forma bastante ligera de manejar muchas imágenes de respaldo.
fuente
Usando Jquery podrías hacer algo como esto:
fuente
Para cualquier imagen, solo use este código javascript:
donde
ptImage
es una<img>
dirección de etiqueta obtenida pordocument.getElementById()
.fuente
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é:
Puede estar fuera de tema, pero resolvió mi propio problema y podría ayudar a alguien más también.
fuente
Además de la brillante respuesta de Patrick , para aquellos de ustedes que buscan una solución angular js multiplataforma, aquí están:
Aquí hay un momento en el que estaba jugando tratando de encontrar la solución correcta: http://plnkr.co/edit/nL6FQ6kMK33NJeW8DVDY?p=preview
fuente
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:
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:
fuente
¡¡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
fuente