62 votes

Détection d'une image 404 en Javascript

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

Je cherche un moyen de détecter qu'une certaine image n'a pas réussi à se charger correctement (404) dans un autre navigateur. 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 depuis s3.

1 votes

IIRC, il y a un événement onerror pour les images... devguru.com/technologies/javascript/10916.asp

2 votes

1 votes

@Dorathoto pourquoi la prime ? La réponse la plus votée est la meilleure : stackoverflow.com/questions/3019077/

66voto

SLaks Points 391154

Manipuler le <img> de l'élément onerror événement.

10 votes

@xal : Assurez-vous simplement d'accrocher le error événement antes de vous définissez le src (si vous faites cela avec new Image ou document.createElement("img") plutôt que par une chaîne HTML). Sinon, vous vous trouvez dans une situation de course et l'événement pourrait se déclencher avant que vous ne commenciez à le traiter (tout comme la fonction load événement).

1 votes

@T.J : Pas nécessairement. Javascript s'exécute sur le fil d'exécution de l'interface utilisateur, donc si vous traitez l'événement immédiatement après avoir configuré la fonction src il ne devrait pas y avoir de risque. Cependant, vous avez toujours raison,

9 votes

Javascript s'exécute sur le thread Javascript, qui sur certains navigateurs est également le fil conducteur de l'interface utilisateur. Ce n'est pas nécessairement le fil de téléchargement. J'ai aidé des gens à corriger des bugs causés précisément par cela, en mettant src avant de fixer un load manipulateur. Il y a une condition de course là. Si le gestionnaire est déjà enregistré, le code de traitement de l'événement le placera sur la pile d'exécution pour être exécuté une fois que le thread JS sera disponible pour faire autre chose. Si vous ne l'avez pas, vous pouvez manquer l'événement.

39voto

Dorathoto Points 365

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>

PS : c'est du pur javascript ! vous n'avez pas besoin de bibliothèques. (Vanilla JS)

Exemple dans Fidler

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

12voto

unomi Points 1846

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'
});

0 votes

Cela soulève un bon point. Vous (OP) devez charger les images avec des paramètres de chaîne de requête aléatoires.

7 votes

Le lien est mort. Cette réponse devrait être modifiée pour contenir du contenu ou se voir retirer sa coche verte.

0 votes

KISS (pour Keep It Super Simple)

11voto

oasisfleeting Points 101

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);

3voto

griegs Points 14142

Ce site explique en détail comment procéder.

Détecter les images cassées en JavaScript

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X