Повторный запуск .getJSON на .click для возврата новых результатов (jQuery/AJAX)

Это сводит меня с ума, но сначала я хотел бы извиниться. Я очень новичок в javascript/jquery. Однако я сделал все возможное, чтобы решить эту проблему, неустанно ища, и безрезультатно.

Вот моя проблема: я реализую фотогалерею Flickr для клиента, потому что она настаивает на использовании ее для загрузки своих фотографий. Для этого я использую купленную мной галерею слайдеров и немного jQuery/AJAX для создания всех функций/запросов. Слайдер — это скрипт jQuery, который использует специально структурированные селекторы для создания слайд-шоу. Структура такая:

<div class="slider">
    <div class="slider-item">
        <img src="path/to/img.jpg"/>
        <img class="thumbnail" src="path/to/img_thumbnail.jpg"/>
        <div class="caption">My Caption</div>
        <div class="thumbnail-caption">My Thumb Caption</div>
    </div>
</div>

Функция, которую я настраиваю, выглядит так:

   var $currentPage = 1;
    var $totalPages;
    var $sliderHTML = "<div class='slider'></div>";
    var $perPage = 18;

    function flickr(){
       $(function (){
            $($sliderHTML).prependTo("#portfolio");
            $.getJSON('http://path/to/flickr?perpage=' + $perPage + '&page=' + $currentPage + '&format=json&jsoncallback=?',
                function(data){

                    $totalPages = Math.ceil(data.photos.total / $perPage);

                    $.each(data.photos.photo, function(i,item){

                   // Loop results and grab all variables I need - Examples omitted

                   // After which, append variables to string

               var $sliderItem = '<div class="slider-item"><img height="' + imgHeight + '" src="' + photoURLo + '" alt="' + photoTitle + '" /><img height="75" width="75" class="thumbnail" src="' + photoURLm + '" alt="' + photoTitle + '" /><div class="caption">' + photoTitle + '</div><div class="thumbnailCaption">' + photoTitle + '</div></div>';

                   // Then append to the main div 

                  $($sliderItem).appendTo(".slider");

           });
      });

    }

// Finally call the function on document.ready

$(document).ready(function(){
   flickr();
});

Чтобы убедиться, что ползунок не загружается до тех пор, пока функция flickr не будет завершена (что вызывало ошибки), я просто обернул его функцией и вызвал ее в window.load. который отлично работает. И, наконец, я инициализирую ползунок с событием window.load.

$(window).load(aSlider()); // loads the slider script
$(window).load(advSlider()); // initializes the slider

Вся установка работает отлично. Изначально.

Вот в чем проблема. Мне нужно вызвать больше фотографий, а это вообще не работает! Вот фрагмент кода в моем HTML:

 <script type="text/javascript">
        $('#moreSlides').click(function (){
            if($totalPages == $currentPage){ //checks for last page
                $currentPage = 1;            //resets to page one
            }
            else {
                $currentPage++;      // increments page 
            }
            $('.slider').remove();      //removes entire slider div              
            flickr();
            $(".slider-item").ajaxComplete(aSlider());
            advSlider();
        });
 </script>

Так или иначе, это всегда терпит неудачу. Я попытался пройти через это событие щелчка в консоли, и в основном оно выглядит так: оно переходит к функции flickr() и просто передает ее вместо выполнения функции (что, как я вижу, произойдет, если я пройду через нее в консоль при загрузке). Тем не менее, в конечном итоге он выполняет функцию... он создает div class=slider и внутри него мою анимацию загрузки, но после этого он не загружает элементы слайда до тех пор, пока не выполнит функцию aSlider().

Я вручную воспроизвел в консоли то, что хочу, и все работает нормально: Увеличьте $currentPage: check. Удалите div .slider: проверьте. Выполните flickr():check. Выполнить aSlider: проверить. Инициализировать advSlider(): проверить. Все работает отлично, отображаются все изображения второй страницы.

Что-то не так с последовательностью, и я просто не знаю, что это такое. Я пробовал все, что мог найти, чтобы заставить aSlider ждать, но это не работает. Пожалуйста помоги!

Спасибо


person bfricka    schedule 01.06.2011    source источник
comment
я думаю, что вызов advSlider() также должен быть в обработчике ajaxComplete. Хотя не знаю проблема ли в этом   -  person Andy    schedule 02.06.2011
comment
Я тоже пробовал это, в том числе с использованием более общего $(window).ajaxComplete(). Хотя пока ничего не работает.   -  person bfricka    schedule 02.06.2011


Ответы (1)


В итоге я решил это, создав цикл setTimeout (с операторами if).

function loadSlides(){
    if($totalPages != $currentPage){  // Making sure we're not on the last page, which may not have the exact $perPage number
        if($('.slider-item').size() == $perPage){ // See if all slides have loaded by counting number of .slider-item and comparing to $perPage variable
            $('#loader').remove();  // Remove loading animation
                aSlider();  // Execute Slider code
                setTimeout(function(){
                    advSlider();  // Instantiate slider (this may not be necessary on the setTimeout here, just being safe)
                },50);
        }
        else {
            setTimeout(function(){  // If all slides haven't loaded, wait 20ms and retry the function.
                loadSlides();
                    },20);
             }
                    }
    else {
        if($('.slider-item').size() == $lastPage){  //This is the same thing as about just takes into account $lastPage instead of $perPage
            $('#loader').remove();
            aSlider();
            setTimeout(function(){
                advSlider();
            },50);
         }
         else {
             setTimeout(function(){
                 loadSlides();
             },20);
         }
    }
}

Это то, что я должен был сделать, чтобы сделать эту работу. Я надеюсь, что это поможет кому-то, потому что getJSON не может быть загружен синхронно, и это кажется распространенной проблемой. Хотя setTimeout является своего рода хаком, его использование позволит вашему коду работать быстрее, чем ввод некоторого общего числа, как это делают некоторые люди:

$(document).ready(function(){
    setTimeout(function(){
    aSlider();
    },1600);
});

Подобное использование setTimeout ужасно, потому что иногда оно слишком длинное, а иногда все еще недостаточно долгое. Поэтому, чтобы заставить его всегда работать правильно, вы должны установить ужасно высокий тайм-аут.

Как я уже сказал, я новичок во всем этом, поэтому, если у кого-то есть лучший способ написать это или сделать то же самое, не стесняйтесь отвечать!

person bfricka    schedule 10.06.2011
comment
Кроме того... Это позволило всему работать в IE8, который, похоже, игнорирует порядок $(window).load(). - person bfricka; 10.06.2011