web-dev-qa-db-fra.com

Détection d'une image 404 en javascript

Après qu'un utilisateur a téléchargé un fichier, nous devons effectuer un traitement supplémentaire avec les images, comme le redimensionnement et le téléchargement vers S3. Cela peut prendre jusqu'à 10 secondes supplémentaires. Évidemment, nous le faisons en arrière-plan. Cependant, nous voulons montrer immédiatement à l'utilisateur la page de résultats et simplement montrer les filateurs en place jusqu'à ce que les images arrivent dans leur domicile permanent sur s3.

Je cherche un moyen de détecter qu'une certaine image n'a pas pu se charger correctement (404) de manière croisée. Si cela se produit, nous voulons utiliser JS pour montrer un spinner à sa place et recharger l'image toutes les quelques secondes jusqu'à ce qu'elle puisse être chargée avec succès à partir de s3.

50
Tobias Lütke

De: http://lucassmith.name/2008/11/is-my-image-loaded.html

// First a couple helper functions
function $(id) {
    return !id || id.nodeType === 1 ? id : document.getElementById(id);
}
function isType(o,t) {    return (typeof o).indexOf(t.charAt(0).toLowerCase()) === 0;}

// Here's the meat and potatoes
function image(src,cfg) {    var img, prop, target;
    cfg = cfg || (isType(src,'o') ? src : {});

    img = $(src);
    if (img) {
        src = cfg.src || img.src;
    } else {
        img = document.createElement('img');
        src = src || cfg.src;
    }

    if (!src) {
        return null;
    }

    prop = isType(img.naturalWidth,'u') ? 'width' : 'naturalWidth';
    img.alt = cfg.alt || img.alt;

    // Add the image and insert if requested (must be on DOM to load or
    // pull from cache)
    img.src = src;

    target = $(cfg.target);
    if (target) {
        target.insertBefore(img, $(cfg.insertBefore) || null);
    }

    // Loaded?
    if (img.complete) {
        if (img[prop]) {
            if (isType(cfg.success,'f')) {
                cfg.success.call(img);
            }
        } else {
            if (isType(cfg.failure,'f')) {
                cfg.failure.call(img);
            }
        }
    } else {
        if (isType(cfg.success,'f')) {
            img.onload = cfg.success;
        }
        if (isType(cfg.failure,'f')) {
            img.onerror = cfg.failure;
        }
    }

    return img;
}

Et voici comment l'utiliser:

image('imgId',{
    success : function () { alert(this.width); },
    failure : function () { alert('Damn your eyes!'); },
});

image('http://somedomain.com/image/typooed_url.jpg', {
    success : function () {...},
    failure : function () {...},
    target : 'myContainerId',
    insertBefore : 'someChildOfmyContainerId'
});
10
unomi

Gérez l'événement onerror de l'élément <img>.

51
SLaks

Première option:

<img src="picture1.gif" onerror="this.onerror=null;this.src='missing.gif';"/>

Deuxième option:

<html>
<head>
<script type="text/javascript">
    function ImgError(source){
        source.src = "/noimage.gif";
        source.onerror = "";
        return true;
    }
</script>
</head>
<body>
    <img src="image_example1.jpg" onerror="ImgError(this)" />
</body>
</html>

Exemple dans Fidler

https://jsfiddle.net/dorathoto/8z4Ltzp8/63/

18
Dorathoto

il suffit de lier le déclencheur attr sur l'événement d'erreur.

$(myimgvar).bind('error',function(ev){
    //error has been thrown
    $(this).attr('src','/path/to/no-artwork-available.jpg');
}).attr('src',urlvar);
9
oasisfleeting

Je viens de faire

if ($('#img')[0].naturalWidth > 0) {

comme je l'ai remarqué, il n'y avait pas de largeur naturelle si l'image était 404.

Cependant, je peux comprendre vouloir utiliser une méthode ci-dessus.

1
Adam Mac

Cela a fonctionné pour moi (le mien est en coffeescript). Vous devrez bien sûr le remplacer par un spinner.

checkImages = ->
  $("img").each ->
    $(this).error ->
      $(this).attr("src", "../default/image.jpg")

$(document).on('page:load', checkImages)

Je suppose que l'équivalent javascript est quelque chose comme

function checkImages() {
  $("img").each(function() {
    $(this).error(function() {
      $(this).attr("src", "../default/image.jpg");
    });
  });
};

$ (document) .on ("page: charger", checkImages);

0
dav1dhunt