Cómo ocultar silenciosamente el icono "Imagen no encontrada" cuando no se encuentra la imagen de origen src


91

¿Sabe cómo ocultar el clásico icono de "Imagen no encontrada" de una página HTML renderizada cuando no se encuentra un archivo de imagen?

¿Algún método de trabajo que utilice JavaScript / jQuery / CSS?


La respuesta de Andy es correcta, sin embargo, es posible que desee utilizar style.vsibility en su lugar. Si configura la visibilidad, el elemento aún conserva su espacio en su documento, por lo que no hay movimientos graciosos del documento.
Christian

No veo el punto. No se supone que debe intentar acceder a ningún recurso existente de su código html. El uso de javascript para ocultar recursos mal negociados parece ser una solución desagradable para mí.
Boris Delormas

1
@Kaaviar Estás perdiendo el punto. Hay muchas imágenes de enlaces directos rotas aquí en Stack Overflow debido al hecho de que las imágenes pueden estar disponibles en el momento de la publicación, pero no disponibles algunos meses después. Estas imágenes se ocultan silenciosa y suavemente.
systemmpuntoout

1
@systempuntoout: No estoy seguro de por qué los dos reciben un trato diferente. Probé una imagen rota en Firefox y Chrome, no se muestra en Firefox pero se muestra como rota en Chrome. Está claro que esto es algo que Firefox está decidiendo por sí solo, ya que no parece que ningún estilo lo afecte. por cierto, gran trabajo en StackPrinter.
Andy E

2
@systempuntoout: descubrí un poco más de información sobre cómo funciona Firefox con esto. Vea un violín actualizado y la [pseudoclase propietaria :-moz-broken] ( developer.mozilla.org/en/CSS/:-moz-broken ). Antes solo pensaba para mí mismo que una pseudo clase sería útil para diseñar imágenes rotas.
Andy E

Respuestas:


102

Puede usar el onerrorevento en JavaScript para actuar cuando una imagen no se carga:

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

En jQuery (ya que preguntaste):

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

O para todas las imágenes:

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

Debe usar en visibility: hiddenlugar de .hide()si ocultar las imágenes puede cambiar el diseño. Muchos sitios en la web usan una imagen predeterminada "sin imagen" en su lugar, apuntando el srcatributo a esa imagen cuando la ubicación de la imagen especificada no está disponible.


1
Andy - ¿Cuál sería la solución 'global' para aplicar a TODAS las imágenes? Creo que sería bastante fácil si todos estuvieran en el mismo div - solo me preguntaba acerca de TODAS las imágenes en el documento ...
jim tollan

@jAndy: Estaba bastante seguro de que lo era, pero tu comentario me hizo comprobarlo dos veces. Un rápido Google devolvió esta página de w3schools (lo siento David, si estás leyendo esto) que indica compatibilidad con varios navegadores.
Andy E

2
@jim: si está usando jQuery, puede aplicar el evento a todas las imágenes. simplemente use el selector de etiquetas, por ejemplo $("img").error(function () { /*...*/ });.
Andy E

@Andy E: suena bien, +1. la siguiente pregunta interesante sería, " error" es "delimitable con live()o delegate().
jAndy

3
visibilitySería mejor, ya que displaypuede romper el diseño.
gblazex

114
<img onerror='this.style.display = "none"'>

Desafortunadamente, no puedo usar esta solución porque el contenido html se descarga desde un sitio web de terceros a través de Json y no puedo editarlo. Gracias de cualquier manera.
systemmpuntoout

9
Impresionante, justo lo que necesitaba. ¡Sencillo y no obstructivo, cabe en una plantilla!
Máximo

Aunque ya es bastante viejo, ¡esto es genial! ¿Hay alguna forma de ocultar las etiquetas <a> que rodean mi imagen ahora oculta también?
SJDS

9

Modifiqué ligeramente la solución sugerida por Gary Willoughby, porque muestra brevemente el icono de imagen rota. Mi solución:

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

En mi solución, la imagen está oculta inicialmente y se muestra solo cuando se carga correctamente. Tiene una desventaja: los usuarios no verán imágenes a medio cargar. Y si el usuario ha desactivado JS, nunca verá ninguna imagen


1
... y los usuarios no verán nada, ¡si javascript está desactivado!
yckart

4
@yckart Bueno, si los usuarios tienen JavaScript desactivado, la mayoría de las aplicaciones web útiles no funcionarán de todos modos ...
asombro

<img src="..." onerror="this.style.display = 'none'"/>¿Podría funcionar mejor para los casos de navegador medio cargado y no js?

6

Para ocultar cada error de imagen, simplemente agregue este JavaScript en la parte inferior de su página (justo antes de la etiqueta del cuerpo de cierre):

(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. 
        }
    }
})();

Este es mi enfoque preferido porque prácticamente garantiza que los eventos de error estén vinculados antes de que las imágenes tengan errores y no tenga que agregar atributos de error a cada etiqueta de imagen. Asegúrese de poner este código después de todas sus etiquetas de imagen, pero antes de cualquier otro javascript que esté en <body>; de lo contrario, una carga JS externa bloqueada puede causar la ejecución después de un error de imagen.
gálatas

Este funciona para mí, junto con los consejos de los gálatas, necesito que este JS se ejecute antes de cualquier cosa que pueda retrasarlo.
Adamz

Esto responde a la pregunta original, pero es un proceso unidireccional. Para que las imágenes que se cargan posteriormente sean visibles nuevamente, agregue también un evento de carga. allimgs [i] .onload = function () {this.style.visibility = "visible"; };
TRT 1968

5

Puede que sea un poco tarde para responder, pero aquí está mi intento. Cuando enfrenté el mismo problema, lo solucioné usando un div del tamaño de la imagen y configurando la imagen de fondo para este div. Si no se encuentra la imagen, el div se vuelve transparente, por lo que todo se hace silenciosamente sin el código java-script.


4

Haciendo una investigación rápida sobre la respuesta de Andy E , no es posible live()vincular error.

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

Entonces tienes que ir como

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

vinculante directamente al error event handlercrear un nuevo elemento.


2
+1, la razón de esto es que el evento DOM de error no burbujea. en vivo y delegue el trabajo colocando el controlador de eventos más arriba en la jerarquía DOM y capturando el evento a medida que surge. Por supuesto, los desarrolladores de jQuery han trabajado en torno a esto para algunos eventos como el enfoque y el desenfoque
Andy E

@Andy E: Sí, ya trabajaron alrededor de eso, podría no ser la peor de las ideas para hacer algo similar error. Suena como un nice to havepara mí.
jAndy

3

Encontré un método ingenioso para hacer exactamente esto, sin dejar de ser funcional cuando uso la ng-srcdirectiva en Angular.js y me gusta ...

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

es básicamente un GIF transparente más corto (como se ve 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 )

por supuesto, este gif podría mantenerse dentro de alguna variable global para que no estropee las plantillas.

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

y use

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

etc.


0

Solo usa CSS simple

.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;
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.