Повторно запустив .getJSON в .click, чтобы вернуть новые результаты (jQuery / AJAX) - PullRequest
0 голосов
/ 02 июня 2011

Это сводит меня с ума, но сначала я хотел бы извиниться. Я очень плохо знаком с 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>

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

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

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

Спасибо

1 Ответ

0 голосов
/ 10 июня 2011

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

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

...