23 Stimmen

JavaScript/jQuery-Ereignislistener für das Laden von Bildern - IE-Probleme

Ich suche nach einer Möglichkeit, dies für so viele Browser wie möglich zu implementieren:

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

Dies hat in IE nicht funktioniert, also habe ich gegoogelt und herausgefunden, dass IE-Versionen unter 9 .addEventListener() nicht unterstützen. Ich weiß, dass es ein jQuery-Äquivalent namens .bind() gibt, aber das funktioniert nicht bei einem Image(). Was muss ich ändern, damit dies auch in IE funktioniert?

30voto

Jose Faeti Punkte 11753

IE unterstützt stattdessen attachEvent.

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

Mit jQuery können Sie einfach schreiben

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

Wenn es um Ereignisse geht, würde ich empfehlen, jQuery zu verwenden, wenn dies möglich ist, da es die Browserkompatibilität sicherstellt. Ihr Code wird in allen gängigen Browsern funktionieren und Sie müssen sich keine Sorgen darüber machen.

Beachten Sie auch, dass in IE das Laden des Bildes ohne Zwischenspeicherung erfolgen muss, damit das Ladeereignis ausgelöst wird, sonst wird in IE das Ladeereignis nicht ausgelöst.

Um dies zu erreichen, können Sie eine Dummy-Variable am Ende der URL Ihres Bildes anhängen, wie folgt

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

Einige bekannte Probleme bei der Verwendung der jQuery load-Methode sind

Nachteile des load-Ereignisses bei Verwendung mit Bildern

Eine häufige Herausforderung, die Entwickler mit dem .load() Shortcut lösen wollen, ist die Ausführung einer Funktion, wenn ein Bild (oder eine Sammlung von Bildern) komplett geladen wurde. Es gibt mehrere bekannte Nachteile, die beachtet werden sollten. Dazu gehören:

  • Es funktioniert nicht konsequent und zuverlässig in allen Browsern
  • Es wird in WebKit nicht korrekt ausgelöst, wenn die Bildquelle auf dieselbe Quelle wie zuvor gesetzt ist
  • Es wird nicht korrekt im DOM-Baum nach oben übertragen
  • Kann aufhören, für Bilder zu funktionieren, die bereits im Browsercache gespeichert sind

Sehen Sie sich die jQuery-Dokumentation für weitere Informationen an.

8voto

Alex Punkte 9017

Sie müssen .attachEvent() anstelle von .addEventListener() verwenden.

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

2voto

pimvdb Punkte 146174

new Image gibt im Grunde ein Tag zurück, sodass Sie in jQuery wie folgt coden können: http://jsfiddle.net/pimvdb/LAuUR/1/.

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

BEARBEITEN: Im Falle des Ladens gültiger Bilder

$('.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 = $("", {
    src: img_src
  });

  $img.on('load', function() {
    $('.buttons').append($img);
  });

  $img.on('error', function() {
  });

});

2voto

Shef Punkte 43517

Sie können attachEvent verwenden, aber ich würde es bevorzugen, wenn Sie den addEventListener-Listener selbst hinzufügen würden. Hier ist der Code auf diesem MDN-Link zum Hinzufügen des Event-Listeners:

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); }
        }
    };
}

1voto

tobek Punkte 4059

Der beste Weg, dies jetzt zu tun, besteht wahrscheinlich darin, jQuery und das jQuery-Plugin imagesLoaded zu verwenden, anstatt jQuery's eingebautes load() oder plain JS. Das Plugin kümmert sich um die verschiedenen Browser-Macken, auf die in der jQuery-Dokumentation verwiesen wird, insbesondere in Bezug auf zwischengespeicherte Bilder und das erneute Auslösen des Callbacks, wenn die src des neuen Bildes die gleiche ist. Einfach jquery.imagesloaded.min.js herunterladen, mit hinzufügen und los geht's:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X