55 votes

Méthode indépendante du navigateur pour détecter si l'image a été chargée.

Dans IE, vous pouvez utiliser onreadystatechange. Il y a aussi onload, mais je lis choses effrayantes . jQuery termine l'événement de chargement du DOM de façon très agréable avec "ready". Il est probable que j'ignore tout simplement l'implémentation du chargement d'image d'une autre belle bibliothèque.

Le contexte est le suivant : je génère des images de manière dynamique (via des rappels de serveur) qui peuvent prendre un certain temps à télécharger. Dans mon code réservé à IE, je définis le src de l'élément img, puis lorsque l'événement onreadystatechange se déclenche avec le statut "complete", je l'ajoute au DOM pour que l'utilisateur le voie.

Je me contenterais d'une solution JavaScript "native" ou d'un lien vers une bibliothèque qui ferait le travail. Il existe tellement de bibliothèques et je suis sûr qu'il s'agit simplement d'un cas où je ne connais pas la bonne. Cela dit, nous utilisons déjà jQuery, et je n'ai pas envie d'ajouter une très grosse bibliothèque juste pour obtenir cette fonctionnalité.

0 votes

Je ne comprends pas bien : voulez-vous une solution unique purement JS pour détecter le chargement d'une image, ou cherchez-vous une bibliothèque alternative à jQuery pour détecter le chargement d'une image ?

0 votes

L'un ou l'autre me conviendrait. Je n'abandonnerais pas jQuery, car je l'utilise ailleurs ; j'exprime simplement mon soupçon qu'il s'agit d'un problème bien résolu dans une bibliothèque que je ne connais pas.

0 votes

N'oubliez pas de nous dire ce que vous faites !

47voto

paulj Points 722

NOTA: J'ai écrit ce texte en 2010, les navigateurs utilisés étaient IE 8/9 beta, Firefox 3.x, et Chrome 4.x. Veuillez utiliser ce texte à des fins de recherche uniquement, je doute que vous puissiez copier/coller ce texte dans un navigateur moderne et qu'il fonctionne sans problème.

AVERTISSEMENT : Nous sommes en 2017 maintenant, je reçois encore des points sur ce sujet de temps en temps, s'il vous plaît utiliser uniquement à des fins de recherche. Je n'ai actuellement aucune idée de la façon de détecter l'état de chargement des images, mais il existe probablement des moyens beaucoup plus gracieux de le faire que cela... du moins je l'espère sérieusement. Je recommande fortement de NE PAS utiliser mon code dans un environnement de production sans plus de recherche.

AVERTISSEMENT Deuxième partie Electric Boogaloo : Nous sommes en 2019 maintenant, la plupart des fonctionnalités de jQuery sont intégrées dans vanilla JS maintenant. Si vous l'utilisez encore, il est peut-être temps d'arrêter et d'envisager de passer à MDN et de lire les nouvelles choses amusantes que vanilla JS a à offrir.


Je suis un peu en retard à cette fête, 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 classiques (onclick/onmouseover/etc), en fait, arrêtez tout simplement de les utiliser. Utilisez les méthodes d'événements fournies dans leur API .


Cette alerte aura lieu avant que l'image ne soit ajoutée au corps, car l'événement load est déclenché lorsque l'image est chargée en mémoire. Il fait exactement ce que vous lui demandez : créer une image avec la src de test.jpg, quand test.jpg se charge faire une alerte, puis l'ajouter au corps.

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

Cette alerte, une fois l'image insérée dans le corps, fera à nouveau ce que vous lui avez demandé : créer une image, déclencher un événement (pas de src défini, donc elle n'a pas été chargée), ajouter l'image au corps (toujours pas de src), définir maintenant la src... maintenant l'image est chargée et l'événement est déclenché.

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

Bien entendu, vous pouvez également ajouter un gestionnaire d'erreurs et fusionner un ensemble 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');

A la demande de @ChrisKempen ...

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

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

12 votes

AVERTISSEMENT : Extrait de la documentation de jquery : Avertissements de l'événement load lorsqu'il est utilisé avec des images : Un défi commun que les développeurs tentent de résoudre en utilisant le raccourci .load() est d'exécuter une fonction lorsqu'une image (ou une collection d'images) a été complètement chargée. Il y a plusieurs avertissements connus à ce sujet qui doivent être notés. Il s'agit de : Elle ne fonctionne pas de manière cohérente et fiable sur tous les navigateurs Elle ne s'exécute pas correctement dans WebKit si le src de l'image est le même que précédemment Elle ne remonte pas correctement l'arbre DOM Elle peut cesser de s'exécuter pour les images qui se trouvent déjà dans le cache du navigateur.

1 votes

Je suis encore plus en retard, mais que se passe-t-il si les images ont déjà été ajoutées et que vous devez vérifier si elles ont été chargées ? Merci pour toute réflexion / suggestion ! :)

5 votes

@ChrisKempen -- J'ai ajouté une méthode non événementielle pour vous dans mon message ci-dessus, veuillez également consulter l'article original dont est issu mon code.

11voto

Jason Bunting Points 27534

Selon la spécification du W3C , uniquement les éléments BODY et FRAMESET fournissent un événement "onload" auquel se rattacher. Certains navigateurs le prennent en charge, mais sachez qu'il n'est pas obligatoire pour mettre en œuvre la spécification du W3C.

Cette discussion pourrait être pertinente pour cette discussion, bien que ce ne soit pas nécessairement la réponse dont vous avez besoin :

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


Quelque chose d'autre qui peut être lié à vos besoins, mais peut-être pas, est cette information sur la prise en charge d'un événement "onload" synthétisé pour l'utilisateur. toute charge dynamique Élément du DOM :

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

0 votes

C'est peut-être vrai, mais le chargement des images est un standard de facto (il est disponible depuis Netscape Navigator 4).

0 votes

Bien sûr, je n'ai jamais dit que ce n'était pas quelque chose sur lequel il pouvait compter, je m'assure simplement qu'il est au courant des spécifications - ignorez les spécifications à vos risques et périls.

0 votes

Le problème avec Image.onload que vous mentionnez est spécifique à GWT - voir code.google.com/p/google-web-toolkit/issues/detail?id=863#c5 ; Image.onload doit être placé avant Image.src pour éviter cela, ce qui a déjà été mentionné implicitement par Josh.

6voto

Josh Stodola Points 42410

Le seul moyen fiable que j'ai trouvé est de tout faire côté client comme ceci...

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

1 votes

Bien que quelques navigateurs le prennent en charge, l'événement "onload" n'est pas pris en charge par la norme du W3C et, par conséquent, tous les navigateurs n'ont pas besoin de le prendre en charge ou ne doivent pas le faire.

3voto

Sebastian Good Points 3146

Bon, je vais essayer de résumer les différentes réponses partielles ici (y compris la mienne).

Il semblerait que la réponse soit d'utiliser onload, qui est "largement supporté" bien que non officiellement requis selon les normes. Notez que pour IE en particulier, vous devez définir onLoad avant de définir l'attribut src, sinon il se peut que l'événement onload ne soit pas déclenché lors du chargement d'une image à partir du cache. Dans tous les cas, il s'agit d'une bonne pratique : configurez vos gestionnaires d'événements avant de commencer à déclencher des événements. Lorsque onload n'est pas pris en charge, il faut supposer que la fonctionnalité n'est tout simplement pas disponible.

3voto

Christoph Points 64389

Je pense onload devrait fonctionner correctement. Devez-vous générer le balisage des images ou pouvez-vous les ajouter de manière statique ? Dans ce dernier cas, je vous suggère ce qui suit :

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

Alternativement, vous pouvez utiliser window.onload pour rendre toutes les images visibles en même temps - window.onload se déclenche après que toutes les ressources externes ont fini d'être chargées.

Si vous voulez ajouter les images dynamiquement, vous devez d'abord attendre que le DOM soit prêt à être modifié, c'est-à-dire utiliser jQuery ou implémenter votre propre hack DOMContentLoaded pour les navigateurs qui ne le supportent pas nativement.

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

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

1 votes

Bien que quelques navigateurs le prennent en charge, l'événement "onload" n'est pas pris en charge par la norme du W3C et, par conséquent, tous les navigateurs n'ont pas besoin de le prendre en charge ou ne doivent pas le faire.

0 votes

Eh bien, lorsque "quelques navigateurs" semblent être tous les navigateurs grand public depuis NN4, on peut raisonnablement supposer que la fonctionnalité ne disparaîtra pas de sitôt. Aussi triste que cela puisse être, les spécifications du W3C reflètent rarement la réalité à laquelle les développeurs web sont confrontés...

0 votes

Encore une fois, je suis conscient de cela, mais il est toujours bon de noter ce que disent les spécifications, ne serait-ce que pour comprendre exactement ce que vous soulignez - qu'elles sont déconnectées de la réalité et doivent être mises à jour. Au fait, qu'est-ce que "js-hacks" et pourquoi est-il nécessaire ? J'ai remarqué sur votre profil que vous l'avez créé, mais il est difficile de découvrir ce que c'est, car votre site Web manque d'informations et je n'ai pas le temps de lire tous les fichiers à la recherche de cette information.

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