2011-01-23 3 views
34

Я пытаюсь выполнить вызов Ajax с jQuery, который работает хорошо. Я использую событие успеха для отображения данных. Кажется, однако, что успех запускается, как только загружается внешний HTML-файл. Если есть большие изображения, они продолжают загружаться после их показа. Есть ли способ отображать содержимое после того, как все будет полностью загружено? Вот код:jQuery Ajax wait, пока все изображения не будут загружены

$('#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); 
    } 
}); 

ответ

39

Плагин, который написал @alex, по какой-то причине не работал для меня ... Я не мог понять, почему. Но его код вдохновил меня придумать более легкое решение, которое работает для меня. Он использует обещания jquery. Обратите внимание: в отличие от плагина @alex, это не попытка учета фоновых изображений на элементах, а только элементов 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); 

} 

Затем вы можете использовать это что-то вроде этого:

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

Надеется, что это полезно для кого-то.

Обратите внимание, что при использовании вышеуказанного кода, если одна из ошибок изображения (например, из-за неправильного URL-адреса), обещание все равно разрешено, и ошибка игнорируется. Это может быть то, что вы хотите, но, в зависимости от вашей ситуации, вы можете вместо этого отказаться от того, что вы делаете, если изображение не загружается.В этом случае вы могли бы заменить OnError строку следующим образом:

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

И поймать ошибку вроде этого:

$('#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

Это отлично работает! Благодарю. –

+0

Это прекрасно работает. Спасибо. – J82

+0

похоже, что это может создать утечку памяти. каждый раз, когда вы делаете вызов ajax, вы создаете дубликат каждого изображения на странице в памяти и присоединяете событие к каждому новому объекту изображения, сохраняя объект изображения в памяти после выполнения функции imagesLoaded. Как только все объекты дублированного изображения загружаются, когда они удаляются из памяти? Непосредственно после выполнения обратного вызова события onload? –

0

Посмотрите в использовании .load Jquery() в

который имеет описание:

Событие нагрузки передается элементу, когда он и все суб- элементы были полностью загружены. Это событие может быть отправлено любому элементу, связанному с URL: изображениями, сценариями, фреймами, iframe и объектом window.

+0

вещи я не могу отключить асинхронные вызовы с нагрузкой и установить кэш варианты права? – robs

10

Вы можете связать что-то к событиям нагрузки, чтобы знать, когда они сделаны:

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

Или вы могли бы использовать this plugin.

+1

О, боже, ты понятия не имеешь, сколько мне помогло, я искал решение часами ... большое спасибо: D – Linas

+5

.on(), по-видимому, рекомендуется использовать .bind() сейчас – 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

я думаю, что лучше использует этот

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

Этот метод является более общим, но Я нахожу, что он отлично работает! –

+6

Это не сработает, поскольку '$ (document) .ready()' и '$ (window) .load()' не запускаются после запроса AJAX. – Andreyco

16

Вы можете использовать мой JQuery плагин, waitForImages ...

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

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

    } 
}); 

Это будет загружать материал в свой элемент, скрывать , а затем перетащите его после того, как потоки img загружены.

+0

действительно красивые плагины, которые решают проблему кладки – ajreal

+1

@alex, могу ли я использовать это для добавления также, в основном, я делаю бесконечные элементы прокрутки и добавления в существующий контейнер вместе с другими изображениями – kobe

+0

@alex, спасибо большое за ваш плагин, i дал мой контейнер div в append и его работа просто отлично – kobe

4

это вызывает на каждом Img нагрузки отдельно:

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

я использовал :

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

Попробуйте этот код. Он работает нормально.

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

Вы можете использовать imagesloaded плагин, который является работа с JavaScript и JQuery, попробуйте использовать внутри AJAX success функцию обратного вызова загруженного содержимого, и скрыть все содержимое в то время как imagesloaded функция обратного вызова не вызывает, смотри ниже пример кода

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

    } 
}); 
0

У меня небольшая ошибка, когда никакие изображения не найдены плагином из решения Даниэля.

Только в случае, если некоторые еще получить тот же вопрос:

Изменение:

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

To:

// if there's no images, just return an already resolved promise 
    if (!$imgs.length) { 
     var dfd = $.Deferred(); 
     return dfd.resolve().promise(); 
    } 
Смежные вопросы