2011-01-23 14 views
34

Próbuję wykonać połączenie Ajax z jQuery, który działa dobrze. Używam zdarzenia sukcesu do wyświetlania danych. Wydaje się jednak, że sukces zostanie uruchomiony natychmiast po załadowaniu zewnętrznego pliku HTML. Jeśli są duże obrazy, nadal ładują się po ich wyświetleniu. Czy istnieje sposób wyświetlenia zawartości po pełnym załadowaniu? Oto kod:jQuery Ajax czekać, aż wszystkie obrazy są załadowane

$('#divajax').html('<br><div style="text-align: center;"><img src="res/ajax-loader.gif"></div>'); 
$.ajax({ 
    cache: false, 
    url: 'ajax/content.php', 
    success: function(data) { 
      $('#divajax').html(data); 
    } 
}); 

Odpowiedz

39

Wtyczka, którą napisał @alex, nie zadziałała dla mnie z jakiegoś powodu ... Nie mogłem zrozumieć dlaczego. Ale jego kod zainspirował mnie do opracowania bardziej lekkiego rozwiązania, które dla mnie działa. Używa jquery obietnic. Zauważ, że w przeciwieństwie do wtyczki @alex, to nie próbuje uwzględniać obrazów tła na elementach, tylko elementy img.

// Fn to allow an event to fire after all images are loaded 
$.fn.imagesLoaded = function() { 

    // get all the images (excluding those with no src attribute) 
    var $imgs = this.find('img[src!=""]'); 
    // if there's no images, just return an already resolved promise 
    if (!$imgs.length) {return $.Deferred().resolve().promise();} 

    // for each image, add a deferred object to the array which resolves when the image is loaded (or if loading fails) 
    var dfds = []; 
    $imgs.each(function(){ 

     var dfd = $.Deferred(); 
     dfds.push(dfd); 
     var img = new Image(); 
     img.onload = function(){dfd.resolve();} 
     img.onerror = function(){dfd.resolve();} 
     img.src = this.src; 

    }); 

    // return a master promise object which will resolve when all the deferred objects have resolved 
    // IE - when all the images are loaded 
    return $.when.apply($,dfds); 

} 

Wtedy można go używać coś takiego:

$.ajax({ 
    cache: false, 
    url: 'ajax/content.php', 
    success: function(data) { 
     $('#divajax').html(data).imagesLoaded().then(function(){ 
      // do stuff after images are loaded here 
     }); 
    } 
}); 

Mam nadzieję, że pomocne dla kogoś.

Należy zauważyć, że używając powyższego kodu, jeśli jeden z błędów obrazu (np. Z powodu nieprawidłowego adresu URL), obietnica zostanie rozwiązana, a błąd zostanie zignorowany. Może to być tym, czego potrzebujesz, ale w zależności od sytuacji możesz zamiast tego chcieć przerwać cokolwiek robisz, jeśli obraz się nie załaduje.W takim przypadku można zastąpić onError linię następująco:

img.onerror = function(){dfd.reject();} 

i złapać błąd podobny do tego:

$('#divajax').html(data).imagesLoaded().done(function(){ 
    // do stuff after all images are loaded successfully here 
}).fail(function(){ 
    // do stuff if any one of the images fails to load 
}); 
+0

To działa świetnie! Dzięki. –

+0

To działa cudownie. Dziękuję Ci. – J82

+0

wygląda na to, że może to spowodować przeciek pamięci. za każdym razem, gdy wywołujesz wywołanie ajax, tworzysz duplikat każdego obrazu na stronie w pamięci i dołączasz zdarzenie do każdego nowego obiektu obrazu, zachowując obiekt obrazu w pamięci po wykonaniu funkcji imagesLoaded. Po załadowaniu wszystkich zduplikowanych obiektów obrazu, kiedy są one usuwane z pamięci? Bezpośrednio po uruchomieniu wywołania zwrotnego zdarzenia onload? –

0

przyglądać się przy użyciu jQuery .load() za

który ma opis:

Impreza obciążenia jest wysyłany do elementu, kiedy i wszystkich pod- elementy zostały całkowicie załadowane. To zdarzenie można wysłać do dowolnego elementu powiązanego z adresem URL: obrazy, skrypty, ramki, ramki iframe i obiekt okna.

+0

jest rzeczą nie mogę wyłączyć połączenia async z obciążeniem i ustawić cache opcje w porządku? – robs

10

Można powiązać coś do wydarzeń obciążenia wiedzieć kiedy skończysz:

$('<img>').bind('load', function() { 
    $(this).appendTo('body'); 
}); 

Albo można użyć this plugin.

+1

o Boże, nie masz pojęcia, ile mi pomogło, szukałem rozwiązania przez wiele godzin ... dziękuję bardzo: D – Linas

+5

.on() najwyraźniej jest polecany przez .bind() teraz – UpTheCreek

0
$('#divajax').html('<br><div style="text-align: center;"><img src="res/ajax-loader.gif"></div>').load(function() { 
$.ajax({ 
    cache: false, 
    url: 'ajax/content.php', 
    success: function(data) { 
      $('#divajax').html(data); 
    } 
}); 
}); 
-6

myślę, że najlepiej jest przy użyciu tego

$(window).ready(function(){ //load your ajax}) 
+0

Ta metoda jest bardziej ogólna, ale Uważam, że działa świetnie! –

+6

To nie zadziała, ponieważ '$ (document) .ready()' oraz '$ (window) .load()' nie uruchamiają się po żądaniu AJAX. – Andreyco

16

Można używać mojego plugin jQuery, waitForImages ...

$.ajax({ 
    cache: false, 
    url: 'ajax/content.php', 
    success: function(data) { 

     $('#divajax').html(data).hide().waitForImages(function() { 
      $(this).show(); 
     }); 

    } 
}); 

To spowoduje załadowanie rzeczy w swoim żywiole, ukryć , a następnie ponownie załaduj elementy, które kiedyś były potomne: img.

+0

Naprawdę ładne wtyczki, które rozwiązują problem murarski – ajreal

+1

@alex, czy mogę tego użyć do dodania również, w zasadzie robię nieskończony przewijanie i dołączanie elementów do istniejącego kontenera wraz z innymi obrazami – kobe

+0

@alex, dziękuję bardzo za wtyczkę, i dał mój pojemnik div w dołączeniu i jego działa dobrze – kobe

4

to wyzwala w każdym obciążeniu img oddzielnie:

$('img').on('load', function() { 
     // do something 
}); 

i używane :

var loaded = 0; 
$('img').on('load', function() { 
    loaded++; 
    if(loaded == $('img').length){ 
     // do something 
    } 
}); 
0

Spróbuj ten kod. To działa dobrze.

 
$.ajax({ 
    url: "../api/listings", 
    type: 'GET', 
    success: function (html) { 
     $('#container').append(html); 
     $('#container img').on('load', function(){console.log('images loaded')}); 
    }; 
}); 
1

Można użyć imagesloaded wtyczkę, która jest praca z JavaScript i jQuery, spróbuj użyć wewnątrz ajax success funkcji zwrotnej załadowanej treści, a ukryć wszystkie treści podczas imagesloaded funkcja zwrotna nie wywoła, patrz poniżej przykładowy kod

$.ajax({ 
    cache: false, 
    url: 'ajax/content.php', 
    success: function(data) { 
     var $divajax = $('#divajax').html(data).hide(); 
     $divajax.imagesLoaded(function() { 
      $divajax.show(); 
     }); 

    } 
}); 
0

Mam mały błąd, gdy wtyczka z rozwiązania Daniela nie wykryła żadnych obrazów.

wszelki wypadek jakiś inny uzyskać ten sam problem:

Zmiana:

// if there's no images, just return an already resolved promise 
if (!$imgs.length) {return $.Deferred.resolve().promise();} 

Do:

// if there's no images, just return an already resolved promise 
    if (!$imgs.length) { 
     var dfd = $.Deferred(); 
     return dfd.resolve().promise(); 
    } 
Powiązane problemy