Chcę zrobić:
$("img").bind('load', function() {
// do stuff
});
Ale zdarzenie ładowania nie jest uruchamiane, gdy obraz jest ładowany z pamięci podręcznej. Dokumenty jQuery sugerują wtyczkę, aby to naprawić, ale to nie działa
Chcę zrobić:
$("img").bind('load', function() {
// do stuff
});
Ale zdarzenie ładowania nie jest uruchamiane, gdy obraz jest ładowany z pamięci podręcznej. Dokumenty jQuery sugerują wtyczkę, aby to naprawić, ale to nie działa
Odpowiedzi:
Jeśli parametr src
jest już ustawiony, zdarzenie jest uruchamiane w zbuforowanej skrzynce, zanim jeszcze zostanie powiązana procedura obsługi zdarzenia. Aby to naprawić, możesz przejść przez sprawdzanie i wyzwalanie zdarzenia na podstawie .complete
:
$("img").one("load", function() {
// do stuff
}).each(function() {
if(this.complete) {
$(this).load(); // For jQuery < 3.0
// $(this).trigger('load'); // For jQuery >= 3.0
}
});
Zwróć uwagę na zmianę z .bind()
na, .one()
aby moduł obsługi zdarzeń nie uruchamiał się dwukrotnie.
setTimeout(function(){//do stuff},0)
ramach funkcji „load” ... 0 daje systemowi przeglądarki (DOM) jeden dodatkowy haczyk, aby upewnić się, że wszystko jest poprawnie aktualizowane.
.load()
nie wyzwala zdarzenia i ma 1 wymagany argument, użyj .trigger("load")
zamiast tego
Czy mogę zasugerować ponowne załadowanie go do obiektu obrazu innego niż DOM? Jeśli jest buforowany, nie zajmie to wcale czasu, a obciążenie nadal będzie działać. Jeśli nie jest przechowywany w pamięci podręcznej, wyzwoli obciążenie po załadowaniu obrazu, co powinno być w tym samym czasie, gdy zakończy się ładowanie wersji DOM obrazu.
JavaScript:
$(document).ready(function() {
var tmpImg = new Image() ;
tmpImg.src = $('#img').attr('src') ;
tmpImg.onload = function() {
// Run onload code.
} ;
}) ;
Zaktualizowano (do obsługi wielu obrazów i z poprawnie uporządkowanym załącznikiem 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') ;
}) ;
}) ;
load
moduł obsługi przed dodaniem, również to nie zadziała, ale dla jednego obrazu kod OP działa dla wielu :)
#img
jest identyfikatorem, a nie selektorem elementów :) this.src
Działa również , nie trzeba używać jQuery tam, gdzie nie jest to potrzebne :) Ale tworzenie kolejnego obrazu wydaje się przesadą w obu przypadkach IMO.
imageLoaded
, użyjtmp.onload = imageLoaded.bind(this)
Moje proste rozwiązanie, nie wymaga żadnej zewnętrznej wtyczki, a 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 tego w ten sposób:
onImgLoad('img', function(){
// do stuff
});
na przykład, aby zanikać pod obciążeniem, możesz wykonać:
$('img').hide();
onImgLoad('img', function(){
$(this).fadeIn(700);
});
Lub alternatywnie, jeśli wolisz podejście podobne do wtyczek 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);
});
width
, max-height
i odchodzenie height:auto
, często jest to konieczne, aby ustawić wysokość i szerokość tylko wtedy, gdy trzeba rozciągnąć obraz; bardziej niezawodne rozwiązanie byłoby użyć wtyczki jak ImagesLoaded
Czy naprawdę musisz to zrobić z jQuery? Możesz również dołączyć onload
wydarzenie bezpośrednio do swojego obrazu;
<img src="/path/to/image.jpg" onload="doStuff(this);" />
Będzie uruchamiany za każdym razem, gdy obraz zostanie załadowany, z pamięci podręcznej lub nie.
onload
obsługi uruchomi się, gdy obraz zostanie załadowany po raz drugi z pamięci podręcznej?
Możesz także 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();
}
});
load
obsługi, a następnie wywołanie go później w each
funkcji.
Właśnie miałem ten problem, szukałem wszędzie rozwiązania, które nie wymagałoby zabicia mojej pamięci podręcznej ani pobrania wtyczki.
Nie zobaczyłem tego wątku od razu, więc zamiast tego znalazłem coś innego, co jest interesującą poprawką i (myślę) warte opublikowania tutaj:
$('.image').load(function(){
// stuff
}).attr('src', 'new_src');
Właściwie ten pomysł pochodzi 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 przetestowałem to na IE7 i gdzie się zepsuł, zanim teraz działa.
Mam nadzieję, że to pomoże,
Przyjęta odpowiedź faktycznie wyjaśnia, dlaczego:
Jeśli src jest już ustawiony, zdarzenie jest uruchamiane w pamięci podręcznej, zanim zostanie powiązana procedura obsługi zdarzenia.
$image.load(function(){ something(); }).attr('src', $image.attr('src'));
resetowałem oryginalne źródło.
Dzięki użyciu jQuery do wygenerowania nowego obrazu za pomocą src obrazu i przypisaniu bezpośrednio do niego metody load, metoda load jest z powodzeniem wywoływana, gdy jQuery zakończy generowanie nowego obrazu. Działa to dla mnie w IE 8, 9 i 10
$('<img />', {
"src": $("#img").attr("src")
}).load(function(){
// Do something
});
Rozwiązanie znalazłem https://bugs.chromium.org/p/chromium/issues/detail?id=7731#c12 (ten kod pochodzi 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;
Modyfikacja 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 obciążeniu.
src
przed dołączeniem programu onload
obsługi, raz wystarczy.
Wystarczy ponownie dodać argument src w osobnym wierszu po zdefiniowaniu obiektu img. Spowoduje to, że IE uruchomi zdarzenie lad. To brzydkie, 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
Mogę dać ci małą wskazówkę, jeśli chcesz to zrobić:
<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 zrobisz to, gdy przeglądarka buforuje zdjęcia, nie ma problemu, że zawsze wyświetla się img, ale ładuje obraz pod prawdziwym obrazem.
Miałem ten problem z IE, w którym e.target.width byłby niezdefiniowany. Zdarzenie load zadziałałoby, ale nie mogłem uzyskać wymiarów obrazu w IE (działało chrome + FF).
Okazuje się, że musisz poszukać e.currentTarget.naturalWidth i e.currentTarget.naturalHeight .
Po raz kolejny IE robi rzeczy po swojemu (bardziej skomplikowane).
Możesz rozwiązać problem za pomocą wtyczki JAIL, która pozwala również na leniwe ładowanie obrazów (poprawa wydajności strony) i przekazywanie wywołania zwrotnego jako parametru
$('img').asynchImageLoader({callback : function(){...}});
HTML powinien wyglądać
<img name="/global/images/sample1.jpg" src="/global/images/blank.gif" width="width" height="height" />
Jeśli potrzebujesz czystego rozwiązania CSS, ta sztuczka działa bardzo dobrze - użyj obiektu transformacji. Działa to również z obrazami, gdy są one 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