web-dev-qa-db-fra.com

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

Je cherche un moyen de l'implémenter 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 donc j'ai googlé et découvert que les IE inférieurs à 9 ne prennent pas en charge .addEventListener(). Je sais qu'il existe un équivalent jQuery appelé .bind() mais cela ne fonctionne pas sur une Image(). Que dois-je changer pour que cela fonctionne dans IE aussi?

22
matteok

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 vous suggère de l'utiliser car il se chargera de la compatibilité du navigateur. Votre code fonctionnera sur tous les principaux navigateurs et vous n'avez pas à vous en soucier.

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 fictive à la fin de l'URL de votre image, comme ceci

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

Certains problèmes connus liés à la méthode de chargement jQuery sont

Avertissements de l'événement de chargement lorsqu'il est utilisé avec des images

Un défi courant que les développeurs tentent de résoudre à l'aide du raccourci .load () est d'exécuter une fonction lorsqu'une image (ou une collection d'images) est complètement chargée. Il y a plusieurs mises en garde connues à ce sujet qui doivent être notées. Ceux-ci sont:

  • Il ne fonctionne pas de manière cohérente ni fiable sur tous les navigateurs
  • Il ne se déclenche pas correctement dans WebKit si l'image src est définie sur le même src qu'auparavant
  • Il ne fait pas correctement bouillonner l'arborescence DOM
  • Peut cesser de se déclencher pour les images qui vivent déjà dans le cache du navigateur

Voir les documents jQuery pour plus d'informations.

29
Jose Faeti

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 */
  });
}
7
Alex

new Image renvoie essentiellement un <img> tag, 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() {
  });

});
2
pimvdb

Vous pouvez utiliser attachEvent , mais je préférerais plutôt que vous ajoutiez l'écouteur addEventListener 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
Shef

La meilleure façon de le faire maintenant est probablement d'utiliser jQuery et le plugin jQuery imagesLoaded au lieu du load() ou du JS ordinaire de jQuery. Le plugin prend en charge les différentes bizarreries du navigateur auxquelles les documents jQuery se réfèrent, à savoir concernant les images mises en cache et relancer le 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 êtes prêt à partir:

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