How to add a CSS class to images that have not loaded?

I have an HTML page with numerous images presented as follows:

<img alt="img1" width="50" height="120" src="my_image.jpg" />
<img alt="img2" width="50" height="120" src="another_image.jpg" />
<img alt="img3" width="50" height="120" src="yet_another_image.jpg" />

If any of the images do not load for Reason A or B, there will be breaks in the layout or in some browsers, the square of the image will appear with the alternative text, making the whole aspect a little ugly.

Question

How can I through jQuery add a CSS class to images whose loading action failed ?

Example:

<img alt="img1" width="50" height="120" src="my_image.jpg" class="failToLoad" />
Author: Comunidade, 2014-01-04

3 answers

The most "natural" way would be to use onerror (jQuery: error), but care must be taken because this event will only be captured if it occurs after that the handler has already been added. So one solution would be to put the script that adds the class at the beginning of the document (head, or beginning of body - before any img). In order not to get too heavy, a solution without jQuery:

<script type="text/javascript">
function erro(elemento) { 
    elemento.className += ' failToLoad'; // Adiciona a classe às já existentes, se houver
}
</script>
...
<img src="..." onerror="erro(this)" />

Example in jsFiddle .

An alternative way, based on this answer in the English OS, seems to work correctly if it is necessary to put JavaScript at the end (in the onLoad of the document, for example).

$('img').each(function() {
    if (!this.complete || typeof this.naturalWidth == "undefined" || this.naturalWidth == 0) {
        $(this).addClass('failToLoad');
    }
});

Example . The advantage of this technique is that no change in HTML tags is required.

 9
Author: mgibsonbr, 2017-05-23 12:37:26

You can assign an event of error to the desired images and add the Class failToLoad

Example

$("#falha")
.on('error',function(){
   $(this).addClass('failToLoad');
   console.log('Essa imagem nao carregou');
})
.attr('src','falha.png');

Remembering that you can not recover the error after the image and the DOM are loaded , since the browser will already have propagated the event of error when loading the image, so you must insert the src after attaching the event in it.

This difficulty is highlighted in the jQuery API .error()

Example JsFiddle

Solution

An automatic solution would be to use the tags data-*

HTML
<img data-src="falha.png">
JavaScript
//Para cada <img> da página
$('img').each(function(){
    //Selecionar essa imagem
    $(this)
    //Atribuir o evento de erro
    .on('error', function(){
        //Caso ocorra o erro, adicionar a classe failToLoad
        $(this).addClass('failToLoad');
    })
    //Definir o src da imagem recuperando do atributo data-src
    .attr('src',$(this).data('src'));
});

Thus, all your images that have error loading, will automatically win the Class failToLoad

JsFiddle Solution

 3
Author: Victor Debone, 2016-08-24 16:42:01

For new dynamically inserted elements it is possible to do using the MutationObserver. And for the other images just get them and add the event.

var observer = new MutationObserver(
    function(mutations) 
    {
        for (var m in mutations)
        {
            var mutation = mutations[m];

            if (mutation.addedNodes) // todos nodos adicionados
            {
                for (var i = 0; i < mutation.addedNodes.length; ++i)
                {
                    var node = mutation.addedNodes[i];

                    if (node.nodeName == "IMG") // se for imagem
                    {
                        // adiciona o evento "error"
                        // caso o erro ocorra, a classe será adicionada
                        node.addEventListener("error", function() {
                            node.className += " failToLoad";
                        }, false);
                    }
                }
            }
        }
    }
);

// inicia o observer
observer.observe(document, { childList: true, subtree: true });

And for existing elements on the page:

$(function() { // quando a página carregar o DOM

    // para todas imagens da página
    $("img").each(function(i,e) {

        // adiciona o evento
        e.addEventListener("error", function(imgEvents) {
            var img = e;

            e.className += " failToLoad"; // em caso de erro adiciona classe

        }, false);

    });
});

See this example in jsfiddle . Note that dynamically inserted images are also validated. In this example the script is being inserted between the tag <head>.

Note that if the image is external, for example imgur, and you pass a link invalid the site will not generate Error 404 instead it will generate a default image.

 1
Author: BrunoLM, 2014-01-04 17:32:44