webentwicklung-frage-antwort-db.com.de

jQuery-Rückruf beim Laden von Bildern (auch wenn das Bild zwischengespeichert ist)

Ich will das tun:

$("img").bind('load', function() {
  // do stuff
});

Das Ladeereignis wird jedoch nicht ausgelöst, wenn das Bild aus dem Cache geladen wird. Die jQuery-Dokumente schlagen ein Plugin vor, um dies zu beheben, aber es funktioniert nicht

276
Tom Lehman

Wenn src bereits festgelegt ist, wird das Ereignis in der zwischengespeicherten Groß-/Kleinschreibung ausgelöst, bevor Sie überhaupt die Ereignisbehandlungsroutine gebunden bekommen. Um dies zu beheben, können Sie das Ereignis basierend auf .complete Wie folgt überprüfen und auslösen:

$("img").one("load", function() {
  // do stuff
}).each(function() {
  if(this.complete) {
      $(this).load(); // For jQuery < 3.0 
      // $(this).trigger('load'); // For jQuery >= 3.0 
  }
});

Beachten Sie die Änderung von .bind() zu .one() , damit der Ereignishandler nicht zweimal ausgeführt wird.

553
Nick Craver

Kann ich vorschlagen, dass Sie es erneut in ein Nicht-DOM-Image-Objekt laden? Wenn es zwischengespeichert ist, wird dies keine Zeit in Anspruch nehmen, und die Onload wird weiterhin ausgelöst. Wenn es nicht zwischengespeichert ist, wird der Onload ausgelöst, wenn das Image geladen wird. Dies sollte zu der Zeit geschehen, zu der die DOM-Version des Images vollständig geladen ist.

Javascript:

$(document).ready(function() {
    var tmpImg = new Image() ;
    tmpImg.src = $('#img').attr('src') ;
    tmpImg.onload = function() {
        // Run onload code.
    } ;
}) ;

Aktualisiert (für mehrere Bilder und mit korrekt bestelltem Onload-Anhang):

$(document).ready(function() {
    var imageLoaded = function() {
        // Run onload code.
    }
    $('#img').each(function() {
        var tmpImg = new Image() ;
        tmpImg.onload = imageLoaded ;
        tmpImg.src = $(this).attr('src') ;
    }) ;
}) ;
44
Gus

Meine einfache Lösung, es benötigt kein externes Plugin und sollte für gängige Fälle ausreichen:

/**
 * Trigger a callback when the selected images are loaded:
 * @param {String} selector
 * @param {Function} callback
  */
var onImgLoad = function(selector, callback){
    $(selector).each(function(){
        if (this.complete || /*for IE 10-*/ $(this).height() > 0) {
            callback.apply(this);
        }
        else {
            $(this).on('load', function(){
                callback.apply(this);
            });
        }
    });
};

benutze es so:

onImgLoad('img', function(){
    // do stuff
});

um beispielsweise Ihre Bilder beim Laden einzublenden, haben Sie folgende Möglichkeiten:

$('img').hide();
onImgLoad('img', function(){
    $(this).fadeIn(700);
});

Oder als Alternative, wenn Sie einen JQuery-Plugin-ähnlichen Ansatz bevorzugen:

/**
 * Trigger a callback when 'this' image is loaded:
 * @param {Function} callback
 */
(function($){
    $.fn.imgLoad = function(callback) {
        return this.each(function() {
            if (callback) {
                if (this.complete || /*for IE 10-*/ $(this).height() > 0) {
                    callback.apply(this);
                }
                else {
                    $(this).on('load', function(){
                        callback.apply(this);
                    });
                }
            }
        });
    };
})(jQuery);

und benutze es so:

$('img').imgLoad(function(){
    // do stuff
});

zum Beispiel:

$('img').hide().imgLoad(function(){
    $(this).fadeIn(700);
});
36
guari

Müssen Sie es wirklich mit jQuery machen? Sie können das Ereignis onload auch direkt an Ihr Bild anhängen.

<img src="/path/to/image.jpg" onload="doStuff(this);" />

Es wird jedes Mal ausgelöst, wenn das Bild aus dem Cache geladen wurde oder nicht.

23
Björn

Sie können diesen Code auch mit Unterstützung für Ladefehler verwenden:

$("img").on('load', function() {
  // do stuff on success
})
.on('error', function() {
  // do stuff on smth wrong (error 404, etc.)
})
.each(function() {
    if(this.complete) {
      $(this).load();
    } else if(this.error) {
      $(this).error();
    }
});
15

Ich hatte dieses Problem gerade selbst und suchte überall nach einer Lösung, bei der mein Cache nicht gelöscht oder ein Plugin heruntergeladen wurde.

Ich habe diesen Thread nicht sofort gesehen, also habe ich stattdessen etwas anderes gefunden, das eine interessante Lösung darstellt und (wie ich finde) es wert ist, hier veröffentlicht zu werden:

$('.image').load(function(){
    // stuff
}).attr('src', 'new_src');

Ich habe diese Idee tatsächlich aus den Kommentaren hier erhalten: http://www.witheringtree.com/2009/05/image-load-event-binding-with-ie-using-jquery/

Ich habe keine Ahnung, warum es funktioniert, aber ich habe dies auf IE7 getestet und wo es brach, bevor es jetzt funktioniert.

Ich hoffe es hilft,

Bearbeiten

Die akzeptierte Antwort erklärt tatsächlich, warum:

Wenn src bereits festgelegt ist, wird das Ereignis im Cache ausgelöst, bevor Sie den Ereignishandler gebunden bekommen.

13
Sammaye

Eine Lösung, die ich gefunden habe https://bugs.chromium.org/p/chromium/issues/detail?id=7731#c12 (Dieser Code stammt direkt aus dem Kommentar)

var photo = document.getElementById('image_id');
var img = new Image();
img.addEventListener('load', myFunction, false);
img.src = 'http://newimgsource.jpg';
photo.src = img.src;
5
AllisonC

Durch die Verwendung von jQuery zum Generieren eines neuen Images mit dem Quellcode des Images und die direkte Zuweisung der Lademethode wird die Lademethode erfolgreich aufgerufen, wenn jQuery das Generieren des neuen Images abgeschlossen hat. Dies funktioniert für mich in IE 8, 9 und 10

$('<img />', {
    "src": $("#img").attr("src")
}).load(function(){
    // Do something
});
4
nick

Eine Modifikation des GUS-Beispiels:

$(document).ready(function() {
    var tmpImg = new Image() ;
    tmpImg.onload = function() {
        // Run onload code.
    } ;

tmpImg.src = $('#img').attr('src');
})

Stellen Sie die Quelle vor und nach dem Laden ein.

4
Chuck Conway

Fügen Sie einfach das Argument src in einer separaten Zeile hinzu, nachdem das Objekt img definiert wurde. Dies wird IE zum Auslösen des Lad-Ereignisses führen. Es ist hässlich, aber es ist die einfachste Problemumgehung, die ich bisher gefunden habe.

jQuery('<img/>', {
    src: url,
    id: 'whatever'
})
.load(function() {
})
.appendTo('#someelement');
$('#whatever').attr('src', url); // trigger .load on IE
3
Bjørn T. Dahl

Ich kann Ihnen einen kleinen Tipp geben, wenn Sie dies möchten:

<div style="position:relative;width:100px;height:100px">
     <img src="loading.jpg" style='position:absolute;width:100px;height:100px;z-index:0'/>
     <img onLoad="$(this).fadeIn('normal').siblings('img').fadeOut('normal')" src="picture.jpg" style="display:none;position:absolute;width:100px;height:100px;z-index:1"/>
</div>

Wenn Sie dies tun, während der Browser Bilder zwischenspeichert, ist es kein Problem, immer img anzuzeigen, aber img unter echtem Bild zu laden.

1
Josephy Besim

Ich hatte dieses Problem mit IE wo die e.target.width undefiniert wäre. Das Ladeereignis würde ausgelöst, aber ich konnte die Dimensionen des Bildes nicht in IE (chrome + FF hat funktioniert).

Es stellt sich heraus, dass Sie nach e.currentTarget.naturalWidth & e.currentTarget.naturalHeight suchen müssen.

Wieder einmal macht IE) Dinge auf seine eigene (kompliziertere) Weise.

1
Ali

Sie können Ihr Problem mit dem Plugin JAIL lösen, mit dem Sie auch Bilder verzögert laden (zur Verbesserung der Seitenleistung) und den Rückruf übergeben können als Parameter

$('img').asynchImageLoader({callback : function(){...}});

Das HTML sollte so aussehen

<img name="/global/images/sample1.jpg" src="/global/images/blank.gif" width="width" height="height" />
0
sebarmeli

Wenn Sie eine reine CSS-Lösung wünschen, funktioniert dieser Trick sehr gut - verwenden Sie das Transformationsobjekt. Dies funktioniert auch mit Bildern, wenn sie zwischengespeichert sind oder nicht:

CSS:

.main_container{
    position: relative;
    width: 500px;
    height: 300px;
    background-color: #cccccc;
}

.center_horizontally{
  position: absolute;
  width: 100px;
  height: 100px;
  background-color: green;
  left: 50%;
  top: 0;
  transform: translate(-50%,0);
}

.center_vertically{
  position: absolute;
  top: 50%;
  left: 0;
  width: 100px;
  height: 100px;
  background-color: blue;
  transform: translate(0,-50%);
}

.center{
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100px;
  height: 100px;
  background-color: red;
  transform: translate(-50%,-50%);
}

HTML:

<div class="main_container">
  <div class="center_horizontally"></div>
  <div class="center_vertically"></div>
  <div class="center"></div>
  </div>
</div

Codepen-Beispiel

Codepen WENIGER Beispiel

0
neoRiley