Mode indépendant du navigateur permettant de détecter l'image chargée

Dans IE, vous pouvez lancer l'échange de données. Il y a une surcharge, mais je lis des choses effrayantes . JQuery enveloppe l'événement de chargement du DOM très bien avec "prêt". Il semble probable que je n'ignorais pas la mise en œuvre d'une autre bibliothèque de chargement d'image.

Le contexte est que je génère des images dynamiquement (via des rappels de serveur) qui peuvent prendre du temps à télécharger. Dans mon code IE-only, je définis la src de l'élément img, puis, lorsque l'événement onreadystatechange déclenche le statut "complet", je l'ajoute au DOM pour que l'utilisateur le voit.

Je serais heureux avec une solution «native» JavaScript ou un pointeur vers une bibliothèque qui effectue le travail. Il y a tellement de bibliothèques là-bas et je suis sûr que c'est un cas de moi qui ne connais pas la bonne. Cela dit, nous sommes déjà des utilisateurs de jQuery, donc je ne suis pas désireux d'ajouter une très grande bibliothèque juste pour obtenir cette fonctionnalité.

NOTE: J'ai écrit ceci en 2010, les navigateurs dans la nature étaient IE 8/9 beta, Firefox 3.x et Chrome 4.x. Utilisez-le uniquement à des fins de recherche, je doute que vous puissiez copier / coller ceci dans un navigateur moderne et le faire fonctionner sans problème.


Je suis un peu en retard pour cette soirée, peut-être que cette réponse aidera quelqu'un d'autre …

Si vous utilisez jQuery, ne vous embêtez pas avec les gestionnaires d'événements stock (onclick / onmouseover / etc), ne cessez de les utiliser complètement. Utilisez les méthodes d'événement qu'ils ont fournies dans leur API .


Cela alerte, avant que l'image ne soit ajoutée au corps, car l'événement de chargement est déclenché lorsque l'image est chargée dans la mémoire. Il fait exactement ce que vous lui dites: créez une image avec la src de test.jpg, lorsque test.jpg chargez une alerte, puis ajoutez-la au corps.

var img = $('<img src="test.jpg" />'); img.load(function() { alert('Image Loaded'); }); $('body').append(img); 

Cela va alerter, après que l'image est insérée dans le corps, encore une fois, en faisant ce que vous lui avez dit: créer une image, définir un événement (pas de paramètre src, donc ne pas charger), ajouter l'image au corps (toujours No src), définissez maintenant la src … maintenant, l'image est chargée afin que l'événement soit déclenché.

 var img = $('<img />'); img.load(function() { alert('Image Loaded'); }); $('body').append(img); $img.attr('src','test.jpg'); 

Vous pouvez bien sûr ajouter un gestionnaire d'erreur et fusionner un groupe d'événements à l'aide de bind ().

 var img = $('<img />'); img.bind({ load: function() { alert('Image loaded.'); }, error: function() { alert('Error thrown, image didn\'t load, probably a 404.'); } }); $('body').append(img); img.attr('src','test.jpg'); 

Selon la demande de @ChrisKempen …

Voici une façon non événementielle de déterminer si les images sont rompues après la chargement du DOM. Ce code est un dérivé du code d'un article de StereoChrome qui utilise naturalWidth, naturalHeight et complète les attributs pour déterminer si l'image existe.

 $('img').each(function() { if (this.naturalWidth === 0 || this.naturalHeight === 0 || this.complete === false) { alert('broken image'); } }); 

Selon la spécification du W3C , seuls les éléments BODY et FRAMESET fournissent un événement "onload" auquel s'attacher. Certains navigateurs le prennent en charge indépendamment, mais sachez qu'il n'est pas nécessaire d'implémenter la spécification W3C.

Quelque chose qui pourrait être pertinent à cette discussion, mais pas nécessairement la réponse dont vous avez besoin, est cette discussion:

L'événement Image.onload ne déclenche pas sur Internet Explorer lorsque l'image est en cache


Une autre chose qui peut être liée à vos besoins, bien que cela ne soit pas le cas, est-ce que cette information est en rapport avec un événement de "onload" synthétisé pour tout élément DOM chargé de façon dynamique :

Comment puis-je déterminer si un élément DOM créé dynamiquement a été ajouté au DOM?

La seule façon fiable que j'ai trouvée est de faire tout cela sur le côté client comme ça …

 var img = new Image(); img.onload = function() { alert('Done!'); } img.src = '/images/myImage.jpg'; 

Je pense que la onload devrait fonctionner correctement. Est-ce que vous devez générer le balisage pour les images, ou pouvez-vous les ajouter statiquement? Si ce dernier, je suggérerais ce qui suit:

 <img src="foo.png" class="classNeededToHideImage" onload="makeVisible(this)"> 

Alternativement, vous pouvez utiliser window.onload pour rendre toutes les images visibles à la fois – window.onload incendies après que toutes les ressources externes ont fini de charger.

Si vous souhaitez ajouter les images de manière dynamique, vous devez d'abord attendre que le DOM soit prêt à être modifié, c'est-à-dire utiliser jQuery ou mettre en œuvre votre propre hack DOMContentLoaded pour les navigateurs qui ne le supportent pas de manière native.

Ensuite, vous créez vos objets d'image, attribuez les auditeurs onload de les rendre visibles et / ou les ajouter au document.

Encore mieux (mais un peu plus compliqué) serait de créer et de commencer à charger les images immédiatement lorsque le script s'exécute. Sur DOMContentLoaded, vous devez vérifier chaque image complete pour décider de les ajouter immédiatement au document ou d'attendre que l'auditeur de charge de l'image onload .

D'accord, je vais essayer de résumer les différentes réponses partielles ici (y compris les miennes).

Il semblerait que la réponse est d'utiliser onload, qui est «largement supporté» mais qui n'est pas officiellement requis selon les normes. Notez que pour IE en particulier, vous devez configurer onLoad avant de définir l'attribut src ou il ne peut pas déclencher le chargement lors du chargement d'une image à partir du cache. Cela semble être la meilleure pratique en tout cas: configurez vos gestionnaires d'événements avant de commencer les essais de tir. Lorsque la surcharge n'est pas prise en charge, il faut supposer que la fonctionnalité n'est tout simplement pas disponible.

Il semblerait que la réponse soit utiliser onreadystatechange dans IE, et onLoad dans d'autres navigateurs. Si l'un d'eux n'est pas disponible, faites autre chose. OnLoad serait préférable, mais IE ne le déclenche pas lors du chargement d'une image du cache, comme indiqué dans l'une des réponses ci-dessous.

Si je ne me trompe pas en javascript, une étiquette d'image a les événements en charge et onerror

Voici un bit interstant de code que j'ai fait pour cacher des images brisées

Dans une étiquette de style

 img.failed{ display:none; } 

En utilisant l'img onerror, j'ai eu un javascript qui a fait this.className = a échoué et il cacherait l'image si elle était erronée

Mais j'ai peut-être mal compris quel but

HTML

 <img id="myimage" src="http://farm4.static.flickr.com/3106/2819995451_23db3f25fe_t.jpg"/>​ 

SCÉNARIO

 setTimeout(function(){ $('#myimage').attr('src','http://cdn.redmondpie.com/wp-content/uploads/2011/05/canarylogo.png').load(function(){ alert('Main Image Loaded'); $('#myimage').attr('src','image.jpg').bind({ load: function(){ alert('Image loaded.'); }, error: function(){ alert('Image not loaded.'); } }); }); },1000); 

JS Fiddle

http://jsfiddle.net/gerst20051/sLge3/

L'utilisation d'un URI de données est le chemin à parcourir. Cependant, l'utilisation d'un SVG au lieu d'un GIF offre plus de flexibilité. Vous pouvez changer rapidement la taille. Il suffit de l'exécuter dans une console JavaScript:

 var width = 1; var height = 1; 'data:image/svg+xml;base64,' + btoa(`<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}"/>`); 

Exemple de sortie:

 data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxIiBoZWlnaHQ9IjEiLz4= 

J'ai jeté ensemble un utilitaire CodePen rapide pour créer des SVG transparents avec des dimensions arbitraires . C'est assez basique, donc vous devrez le modifier si vous souhaitez ajouter des couleurs ou d'autres fonctionnalités à l'image.

Le plus grand avantage sur une image à un seul pixel est qu'il permet de préserver le rapport d'aspect. Ceci est important pour les images de taille dynamique, car la mise en page est souvent effectuée avant que la src change pour une image réelle (si c'est le but recherché). Jusqu'à ce que la src change, l'image sera carrée, ce qui pourrait ne pas être souhaitable.