wywołanie zwrotne jQuery przy ładowaniu obrazu (nawet gdy obraz jest buforowany)

Chcę zrobić:

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

Ale zdarzenie load nie uruchamia się, gdy obraz jest ładowany z pamięci podręcznej. dokumenty jQuery sugerują wtyczkę , aby to naprawić, ale to nie działa

Author: RRK, 2010-10-07

14 answers

Jeśli src jest już ustawione, to zdarzenie zostanie wywołane w buforowanej sprawie, zanim zostanie przypisana Obsługa zdarzenia. Aby to naprawić, możesz zapętlić sprawdzanie i wyzwalanie zdarzenia na podstawie .complete, w następujący sposób:

$("img").one("load", function() {
  // do stuff
}).each(function() {
  if(this.complete) $(this).load();
});

Zwróć uwagę na zmianę z .bind() na .one() więc opiekun imprezy nie działa dwa razy.

 530
Author: Nick Craver,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-20 20:19:57

Czy Mogę zasugerować ponowne załadowanie go do obiektu obrazu innego niż DOM? Jeśli jest w pamięci podręcznej, nie zajmie to dużo czasu, a ładunek nadal będzie odpalany. Jeśli obraz nie jest buforowany, uruchomi onload po załadowaniu obrazu, co powinno nastąpić w tym samym czasie, w którym wersja DOM obrazu zakończy ładowanie.

Javascript:

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

Zaktualizowano (aby obsłużyć wiele obrazów i poprawnie uporządkować załącznik onload):

$(document).ready(function() {
    var imageLoaded = function() {
        // Run onload code.
    }
    $('#img').each(function() {
        var tmpImg = new Image() ;
        tmpImg.onload = imageLoaded ;
        tmpImg.src = $(this).attr('src') ;
    }) ;
}) ;
 40
Author: Gus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-06 21:54:32

Moje proste rozwiązanie, nie wymaga żadnej zewnętrznej wtyczki i w typowych przypadkach powinno wystarczyć:

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

Użyj go tak:

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

Na przykład, aby zniknąć w obrazach podczas ładowania można zrobić:

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

Lub jako alternatywa, jeśli wolisz podejście podobne do wtyczki jquery:

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

I użyj go w ten sposób:

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

Na przykład:

$('img').hide().imgLoad(function(){
    $(this).fadeIn(700);
});
 31
Author: guari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-20 11:11:10

Czy naprawdę musisz to robić z jQuery? Możesz również dołączyć Zdarzenie onload bezpośrednio do swojego obrazu;

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

Uruchomi się za każdym razem, gdy obraz zostanie załadowany, z pamięci podręcznej lub nie.

 22
Author: Björn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-06 21:34:00

Sam miałem ten problem, szukałem wszędzie rozwiązania, które nie wiązało się z zabijaniem mojej pamięci podręcznej lub pobieraniem wtyczki.

Od razu nie zauważyłem tego wątku, więc znalazłem coś innego, co jest ciekawą poprawką i (myślę) godną zamieszczenia tutaj:

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

W sumie ten pomysł zaczerpnąłem z komentarzy tutaj: http://www.witheringtree.com/2009/05/image-load-event-binding-with-ie-using-jquery/

Nie mam pojęcia dlaczego to działa, ale mam przetestowałem to na IE7 i gdzie się zepsuł zanim teraz działa.

Hope it helps,

Edit

Przyjęta odpowiedź faktycznie wyjaśnia dlaczego:

Jeśli src jest już ustawione, to zdarzenie zostanie wywołane w pamięci podręcznej, zanim zostanie przypisana Obsługa zdarzenia.

 12
Author: Sammaye,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-13 13:29:01

Możesz również użyć tego kodu z obsługą błędu ładowania:

$("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();
    }
});
 11
Author: Piotr Stępniewski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-02 04:57:43

Modyfikacja do przykładu GUS:

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

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

Ustaw źródło przed i po załadowaniu.

 4
Author: Chuck Conway,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-06 21:42:46

Używając jQuery do wygenerowania nowego obrazu z src obrazu i przypisując bezpośrednio do niego metodę load, metoda load jest pomyślnie wywołana, gdy jQuery zakończy generowanie nowego obrazu. To działa dla mnie w IE 8, 9 i 10

$('<img />', {
    "src": $("#img").attr("src")
}).load(function(){
    // Do something
});
 4
Author: nick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-24 17:10:41

Wystarczy ponownie dodać argument src w oddzielnej linii po zdefiniowaniu obiektu img. Spowoduje to oszukanie IE w wyzwalanie zdarzenia lad. Jest brzydki, ale jest to najprostsze obejście, jakie do tej pory znalazłem.

jQuery('<img/>', {
    src: url,
    id: 'whatever'
})
.load(function() {
})
.appendTo('#someelement');
$('#whatever').attr('src', url); // trigger .load on IE
 3
Author: Bjørn T. Dahl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-14 15:59:01

Mogę dać ci małą wskazówkę, jeśli chcesz zrobić tak:

<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>

Jeśli to zrobisz, gdy przeglądarka buforuje zdjęcia, nie ma problemu Zawsze img pokazane, ale Ładowanie img pod rzeczywistym obrazem.

 1
Author: Josephy Besim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-13 07:19:27

Miałem taki problem z IE gdzie cel e.szerokość byłaby nieokreślona. Zdarzenie load odpaliłoby się, ale nie mogłem uzyskać wymiarów obrazu w IE(działał chrome + FF).

Okazuje się, że trzeba szukać e. currentTarget.naturalna & e. currentTarget.naturalHeight .

Po raz kolejny IE robi rzeczy na swój (bardziej skomplikowany) sposób.

 1
Author: Ali,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-12 08:04:02

Rozwiązanie, które znalazłem https://bugs.chromium.org/p/chromium/issues/detail?id=7731#c12 (Ten kod zaczerpnięty bezpośrednio z komentarza)

var photo = document.getElementById('image_id');
var img = new Image();
img.addEventListener('load', myFunction, false);
img.src = 'http://newimgsource.jpg';
photo.src = img.src;
 1
Author: AllisonC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-22 14:06:49

Możesz rozwiązać swój problem za pomocą wtyczki JAIL , która pozwala również leniwie ładować obrazy (poprawiając wydajność strony) i przekazać callback jako parametr

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

HTML powinien wyglądać tak:

<img name="/global/images/sample1.jpg" src="/global/images/blank.gif" width="width" height="height" />
 0
Author: sebarmeli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-09 10:17:05

Jeśli chcesz mieć czyste rozwiązanie CSS, ta sztuczka działa bardzo dobrze-użyj obiektu transform. Działa to również z obrazami, gdy są buforowane lub nie:

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

Przykład Codepen

Przykład Codepen LESS

 0
Author: neoRiley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-10 19:52:18