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.
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'
});
Gérez l'événement onerror
de l'élément <img>
.
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
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);
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.
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);