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?
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.
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 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() {
});
});
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); }
}
};
}
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");
});