Запуск кода jQuery после того, как страница завершит загрузку содержимого AJAX

У меня есть страница, которая загружает контент через AJAX. Среди этого контента есть несколько изображений. Мне нужно немного отформатировать макет страницы в зависимости от размеров изображений (которые различаются), но для того, чтобы получить размеры, мне нужно, чтобы изображения завершили загрузку перед запуском кода. Если бы это была обычная страница (содержимое загружается нормально БЕЗ AJAX), все, что мне нужно сделать, это использовать функцию $(window).load(), но с AJAX она по некоторым причинам не срабатывает. Мне нужен обходной путь: способ выполнить некоторый код после завершения загрузки изображений, загруженных через AJAX.

В принципе, это то, что я пытаюсь сделать

ajaxRequest.onreadystatechange = function(){
        if(ajaxRequest.readyState == 4){
document.getElementById("results").innerHTML=ajaxRequest.responseText;
//the responseText includes images among other information to be loaded 
$(window).load(function() {
...some code
});}}

но $(window).load() никогда не срабатывает, и мне нужно запустить код после завершения загрузки ВСЕХ изображений, поэтому привязка события загрузки к каждому изображению на самом деле не вариант.

У меня есть еще один вопрос, который связан и похож на первый: jQuery $(document).ready, похоже, не срабатывает после загрузки контента через AJAX. Мне это не нужно прямо сейчас, но я определенно буду нуждаться в этом в будущем, так что какие-нибудь обходные пути для этого тоже?

Я был бы очень признателен за вашу помощь и большое спасибо.


person Ilyes Ferchiou    schedule 24.06.2012    source источник
comment
Имейте в виду, что $(element).load) является запросом AJAX. ‹- Редактировать: я был неправ, проигнорируйте этот комментарий   -  person Cranio    schedule 24.06.2012
comment
@Cranio не совсем так, 2 комплекта документов для load() в API   -  person charlietfl    schedule 24.06.2012
comment
я думаю, $(window).bind('load',function) будет событием, которое вы ищете   -  person krichard    schedule 24.06.2012
comment
@charlietfl О, мой плохой, не знал! Извините вас и ОП, и спасибо, что указали.   -  person Cranio    schedule 24.06.2012
comment
@KaiKönig Это работает (адаптировано) в div вместо окна?   -  person Denys Séguret    schedule 24.06.2012
comment
@IlyesFerchiou В любом случае, $(document).ready запускается при загрузке главной страницы и не имеет отношения к AJAX. Вы должны использовать функцию обратного вызова.   -  person Cranio    schedule 24.06.2012
comment
@KaiKönig bind('load',fn) и load(fn) делают то же самое в jQuery API api.jquery.com/load-event   -  person charlietfl    schedule 24.06.2012
comment
@charlietfl спасибо за разъяснения   -  person krichard    schedule 24.06.2012
comment
Дело в том, что в jQuery есть две функции .load(), одна из которых запускает событие при загрузке содержимого (DOM + изображения +...), а другая связана с AJAX и отправляет запрос на страницу. Какой из них выполняется, зависит от аргументов, первый принимает в качестве аргумента функцию, второй принимает в качестве аргументов URL, данные (строку запроса) и функцию обратного вызова. Размещение моего кода в функции обратного вызова запускает его до того, как содержимое будет полностью загружено и отображено, размещение моего кода в обычной функции .load(), которая, в свою очередь, находится в функции AJAX .load(), не работает.   -  person Ilyes Ferchiou    schedule 24.06.2012


Ответы (3)


$(window).load работает только для начальной загрузки страницы.

Единственное чистое решение, которое я вижу, это подсчет изображений (надеясь, что это единственная проблема) и ожидание их загрузки:

$('#results').load('youurl', function() {
    var $images = $('#contenu img');
    var count = $images.length;
    console.log('initial images count : ', count);
    var decrement = function() {
        if (--count==0) {
            console.log('All images loaded');
            // do something                 
        }
    };
    $images.each(function(){
       if (this.complete) {
           decrement();
       } else {
           this.onload = function(){
                decrement();
           };
       }
    });
});

Теперь это можно проверить на этом сайте: щелкните ссылку, чтобы найти рецепт, и посмотри на консоль.

person Denys Séguret    schedule 24.06.2012
comment
Большое спасибо за ваш ответ, эта функция действительно делает весь код намного короче и проще. Я новичок в AJAX, поэтому я использовал первое, что нашел, а именно XMLHttpRequest. Однако, несмотря на то, что эта функция упростила задачу, мой код, помещенный в функцию обратного вызова, запускается сразу после обработки запроса, а НЕ после загрузки всех данных и отображения изображений. В общем, мой код работает, но не может получить размеры изображений, так как он запускается до завершения загрузки изображений, поэтому теперь мой код короче, но у меня все та же проблема. - person Ilyes Ferchiou; 24.06.2012
comment
Ты прав. Я поставил новую (проверенную) версию. Но это не универсально и работает только для изображений. Вам придется расширить его для более сложных случаев. - person Denys Séguret; 24.06.2012
comment
Это именно то, о чем я думал, но, поскольку я знаю, что есть некоторые проблемы с функцией .load(), используемой с изображениями, я хотел избежать этого. По крайней мере, он работает с последними версиями IE, FF и Chrome. Если возникнут какие-либо проблемы с другими браузерами или более ранними версиями, я разберусь с этим. Большое спасибо за то, что написали для меня код, сегодня вы только что в два раза облегчили мне жизнь. И я узнал две новые вещи: функцию загрузки AJAX и (хотя это очевидно): вы можете сделать операцию --count здесь, в рамках проверки условия. Я инженер-механик, так что... И лучший ответ - да. - person Ilyes Ferchiou; 24.06.2012
comment
Ну, на самом деле это работает. Но раньше, на других веб-сайтах, я пытался связать событие load() с изображениями и заметил, что в некоторых случаях (в некоторых старых версиях или в некоторых конкретных случаях) это не работает. Это хорошо известная проблема, вы можете прочитать о ней в разделе Предостережения относительно события загрузки при использовании с изображениями этого веб-сайт - person Ilyes Ferchiou; 24.06.2012

Я считаю, что вам нужен плагин imagesLoaded. После загрузки разметки через AJAX выберите изображения внутри этого div и вызовите для них .imagesLoaded():

$('.article img').imagesLoaded( myCallbackFunction );
person Interrobang    schedule 24.06.2012
comment
Большое спасибо за ваш ответ, но это обходной путь для кэшированных изображений, это не мой случай. Мой код не срабатывает, даже если изображения НЕ кэшируются. И в этом случае я имею дело с изображениями, но в целом, когда у меня есть код для запуска после того, как определенные данные, вставленные через AJAX, полностью отобразятся, я хочу знать, как я могу заставить его работать. - person Ilyes Ferchiou; 24.06.2012
comment
Этот работает. Необходимо выполнить js после загрузки запросов изображения из ответа ajax, и этот плагин делает именно это. - person srgb; 14.09.2012

Кроме того, вы используете XMLHttpRequest... с JQuery это намного проще. Вы можете избавиться от всего кода, который вы разместили, и просто выполните:

$("#results").load("ajaxpage.php", function() { ... some code... });

Это все, что вам нужно. Если вам нужно запустить некоторый код при загрузке окна, используйте ваш $(window).load(). Если вам нужно запустить код после запроса ajax, просто поместите его в функцию обратного вызова () выше

person Cranio    schedule 24.06.2012
comment
Большое спасибо за ваш ответ, но, как я уже сказал Dystroy, размещение моего кода в функции обратного вызова заставляет ее запускаться сразу после обработки запроса, а НЕ после загрузки всех данных и отображения изображений. В общем, мой код работает, но не может получить размеры изображений, так как он запускается до завершения загрузки изображений, поэтому теперь мой код короче, но у меня все та же проблема. - person Ilyes Ferchiou; 24.06.2012