JavaScript / jQuery event listener sur la charge d'image pour tous les navigateurs

Je recherche une façon de mettre en œuvre ceci pour autant de navigateurs que possible:

var image = new Image(); image.addEventListener("load", function() { alert("loaded"); }, false); image.src = "image_url.jpg"; 

Cela n'a pas fonctionné dans IE, alors j'ai googlé et j'ai découvert que les IE inférieurs à 9 ne prennent pas en charge .addEventListener() . Je sais qu'il y a un équivalent jQuery appelé .bind() mais cela ne fonctionne pas sur une Image() . Que dois-je changer pour que cela fonctionne aussi dans IE?

    IE prend en charge attachEvent à la place.

     image.attachEvent("onload", function() { // ... }); 

    Avec jQuery, vous pouvez simplement écrire

     $(image).load(function() { // ... }); 

    En ce qui concerne les événements, si vous avez la possibilité d'utiliser jQuery, je suggérerais l'utiliser car il prendra soin de la compatibilité du navigateur. Votre code fonctionnera sur tous les principaux navigateurs et vous ne devez pas vous en préoccuper.

    Notez également que, pour que l'événement de chargement soit déclenché dans IE, vous devez vous assurer que l'image ne sera pas chargée à partir du cache, sinon IE ne déclenchera pas l'événement de chargement.

    Pour ce faire, vous pouvez ajouter une variable factice à la fin de l'URL de votre image, comme celle-ci

     image.setAttribute( 'src', image.getAttribute('src') + '?v=' + Math.random() ); 

    Certains problèmes connus utilisant la méthode de charge jQuery sont

    Les mises en garde de l'événement de chargement 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 complètement chargée. Il y a plusieurs réserves connues avec ce qui doit être noté. Ceux-ci sont:

    • Il ne fonctionne pas systématiquement ni de manière fiable cross-browser
    • Il ne se déclenche pas correctement dans WebKit si l'image src est définie sur le même code que précédemment
    • Il ne reflète pas correctement l'arbre DOM
    • Peut cesser de prendre feu pour les images qui vivent déjà dans le cache du navigateur

    Consultez les documents jQuery pour plus d'informations.

    Vous devez utiliser .attachEvent() plutôt que .addEventListener() .

     if (image.addEventListener) { image.addEventListener('load', function() { /* do stuff */ }); } else { // it's IE! image.attachEvent('onload', function() { /* do stuff */ }); } 

    new Image renvoie essentiellement une <img> , vous pouvez donc coder dans jQuery comme: http://jsfiddle.net/pimvdb/LAuUR/1/ .

     $("<img>", { src: '...' }) .bind('load', function() { alert('yay'); }); 

    EDIT: en cas de chargement d'images valides

     $('.buttons').html(''); var range = []; for (var i = 1; i <=50; i++) range.push(i); range.forEach(function(i) { var img_src = 'http://i.imgur.com/' + i + '.jpg'; var $img = $("<img>", { src: img_src }); $img.on('load', function() { $('.buttons').append($img); }); $img.on('error', function() { }); }); 

    Vous pouvez utiliser attachEvent , mais je préférerais que vous ajoutiez l'auditeur addEventListener vous-même. Voici le code sur ce lien MDN pour ajouter l'auditeur d'événements:

     if (!Element.prototype.addEventListener) { var oListeners = {}; function runListeners(oEvent) { if (!oEvent) { oEvent = window.event; } for (var iLstId = 0, iElId = 0, oEvtListeners = oListeners[oEvent.type]; iElId < oEvtListeners.aEls.length; iElId++) { if (oEvtListeners.aEls[iElId] === this) { for (iLstId; iLstId < oEvtListeners.aEvts[iElId].length; iLstId++) { oEvtListeners.aEvts[iElId][iLstId].call(this, oEvent); } break; } } } Element.prototype.addEventListener = function (sEventType, fListener /*, useCapture (will be ignored!) */) { if (oListeners.hasOwnProperty(sEventType)) { var oEvtListeners = oListeners[sEventType]; for (var nElIdx = -1, iElId = 0; iElId < oEvtListeners.aEls.length; iElId++) { if (oEvtListeners.aEls[iElId] === this) { nElIdx = iElId; break; } } if (nElIdx === -1) { oEvtListeners.aEls.push(this); oEvtListeners.aEvts.push([fListener]); this["on" + sEventType] = runListeners; } else { var aElListeners = oEvtListeners.aEvts[nElIdx]; if (this["on" + sEventType] !== runListeners) { aElListeners.splice(0); this["on" + sEventType] = runListeners; } for (var iLstId = 0; iLstId < aElListeners.length; iLstId++) { if (aElListeners[iLstId] === fListener) { return; } } aElListeners.push(fListener); } } else { oListeners[sEventType] = { aEls: [this], aEvts: [ [fListener] ] }; this["on" + sEventType] = runListeners; } }; Element.prototype.removeEventListener = function (sEventType, fListener /*, useCapture (will be ignored!) */) { if (!oListeners.hasOwnProperty(sEventType)) { return; } var oEvtListeners = oListeners[sEventType]; for (var nElIdx = -1, iElId = 0; iElId < oEvtListeners.aEls.length; iElId++) { if (oEvtListeners.aEls[iElId] === this) { nElIdx = iElId; break; } } if (nElIdx === -1) { return; } for (var iLstId = 0, aElListeners = oEvtListeners.aEvts[nElIdx]; iLstId < aElListeners.length; iLstId++) { if (aElListeners[iLstId] === fListener) { aElListeners.splice(iLstId, 1); } } }; } 

    La meilleure façon de le faire maintenant est probablement d'utiliser jQuery et les images de plugin jQueryLouées au lieu de la load() intégrée de jQuery load() ou de JS JJ . Le plugin s'occupe des différentes particularités du navigateur auxquelles se réfère le jQuery, notamment en ce qui concerne les images mises en cache et la réactivation du rappel si le src de la nouvelle image est le même. Téléchargez simplement jquery.imagesloaded.min.js , ajoutez-le avec <script src="jquery.imagesloaded.min.js"></script> et vous allez bien:

     $(image).imagesLoaded(function() { alert("loaded"); });