JavaScript/jQuery écouteur d'événement sur chargement de l'image pour tous les navigateurs

je cherche un moyen d'implémenter 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 IE est inférieur à 9 ne supporte pas .addEventListener(). Je sais qu'il y a jQuery équivalent appelé .bind() mais cela ne fonctionne pas sur un Image(). Que dois-je modifier pour que cela fonctionne sous IE?

20
demandé sur Jose Faeti 2011-09-16 13:42:48

5 réponses

IE supporte 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 vous suggérerais de l'utiliser car il s'occupera de la compatibilité du navigateur. Votre code fonctionnera sur tous les navigateurs principaux et vous n'avez pas à vous inquiéter à ce sujet.

Notez aussi que pour que L'événement load soit déclenché dans IE, vous devez vous assurer que l'image ne sera pas chargée depuis le cache, sinon IE ne tirera pas l'événement de charge.

Pour ce faire, vous pouvez ajouter une variable muette à la fin de l'url de votre image, comme ceci

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

certains problèmes connus utilisant la méthode jQuery load sont

mises en garde 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 .charge() raccourci pour exécuter une fonction lorsqu'une image (ou d'une collection de les images) ont complètement chargé. Y sont connu plusieurs mises en garde avec ce qui devrait être noté. Ce sont:

  • Il ne fonctionne pas systématiquement, ni de manière fiable de la croix-navigateur
  • il ne démarre pas correctement dans WebKit si l'image src est même src qu'avant
  • Il n'est pas correctement remonter l'arborescence DOM
  • Peut cesser d'incendie pour les images qui vivent déjà dans le navigateur cache

voir le jQuery docs pour plus d'info.

29
répondu Jose Faeti 2011-09-16 10:22:24

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 */
  });
}
6
répondu Alex 2013-01-17 14:10:15

new Image fondamentalement renvoie un <img> balise, de sorte que vous pouvez code en jQuery de la forme: 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() {
  });

});
3
répondu pimvdb 2016-10-04 09:49:31

Vous pouvez utiliser attachEvent, mais je préférerais vous ajoutez l' addEventListener port d'écoute de vous-même. Voici le code sur ce lien MDN pour ajouter l'écouteur 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); }
        }
    };
}
2
répondu Shef 2011-09-16 10:13:18

La meilleure façon de le faire est sans doute d'utiliser jQuery et le plugin jQuery imagesLoaded au lieu de jQuery est intégré load() ou de la plaine JS. Le plugin prend en charge les différentes bizarreries de navigateur auxquelles se réfèrent les docs jQuery, notamment en ce qui concerne les images mises en cache et le redémarrage du callback si la nouvelle image est src est la même. Il suffit de télécharger jquery.imagesloaded.min.js, ajoutez-la dans avec <script src="jquery.imagesloaded.min.js"></script> et vous êtes bon pour aller:

$(image).imagesLoaded(function() {
    alert("loaded");
});
1
répondu tobek 2013-01-12 06:48:59