Продолжаем совершенствовать сайт на базе wordpress. Речь опять идёт о сайте моей жены. В предыдущей статье описал, как подгружать содержание статьи по нажатию на ссылку “Читать дальше” через AJAX, теперь – обеспечим чтение всего архива без перезагрузки страницы (wordpress бьёт их по страницам, по страницам и будем подгружать).

Начну с конца. Посмотреть результат моей работы Вы можете здесь http://www.nice-tour.nov.ru/news. Просто нажимайте PageDown на своей клавиатуре и следите за скроллбаром – увидите, что содержимое подгржается по ходу Вашего чтения.

Для начала заставим наш сайт самостоятельно нажимать ссылку “следующая страница” в момент, когда пользователь пролистал сайт практически до самой ссылки “следующая страница”. Несмотря на то, что задача простая до невозможности, её решение имеет массу подводных камней. Для начала приведу сценарий на jQuery:

var backgroundAction = false;

jQuery(function() {
    if (!$(".page-container").length) return;
    $(window)
        .bind('scroll', function(e) {
            var content = $(".page-container:last");
            if ( $(window).scrollTop() + (1+1) * $(window).height() > content.offset().top + content.height() ) {
                backgroundAction = true;
                $(".nextpostslink").click();
                backgroundAction = false;
            };
        })
    ;
});

Как видно, скрипт просто примитивен. Сначала проверяю, а есть ли на странице контейнеры “страниц”. Если нет – то и не нужен наш сценарий. Если есть – цепляю обработчик на scroll для окна. Дальше проверяю позицию последнего контейнера “виртуальной страницы” по отношению к окну. И если до его (контейнера) нижней границы (top+height) осталось меньше одной высоты окна (то есть одно нажатие page down, поэтому и написал (1+1)*$(window).height), имитирую нажатие на ссылку (следующая страница). Указанный класса nextpostslink является стандартным в случае wordpress.

Дальше всё будет сложнее. Теперь, собственно, нам и нужно обеспечить возможность AJAX загрузки следующей страницы при нажатии на ссылку (не важно как мы её “нажали” – предыдущим сценарием или мышкой). И для решения этой задачи, к великому моему сожалению, без модификации файлов темы я ничего сделать не смог. Буду благодарен за любые подсказки о том, как обеспечить независимую от темы реакцию на подобный AJAX запрос.

Итак, модифицируем файл темы. Приведу пример на index.php, но править придётся все файлы для архивов (archives.php и так далее, если они есть).


 
';}; }; if (have_posts()) { $post = $posts[0]; // Hack. Set $post so that the_date() works. if( !is_ajax_read_next_page() ) { if(is_category()){ echo '

Архив рубрики: »'.single_cat_title('',FALSE).' «

'; }elseif(is_day()){ echo '

Архив: » '.get_the_time('F jS, Y').'«

'; }elseif(is_month()){ echo '

Архив: » '.get_the_time('F, Y').' «

'; }elseif(is_year()){ echo '

Архив: » '.get_the_time('Y').' «

'; } elseif(is_search()){ echo '

Результаты поиска

'; }elseif(is_author()){ echo '

Автор архива

'; }elseif(isset($_GET['paged']) && !empty($_GET['paged'])){ // If this is a paged archive echo '

Архивы блога

'; }elseif(is_tag()){ echo '

Теги архива: » '.single_tag_title('',FALSE).' «

'; }; ?>
" >
" class="entry">
Рубрики: Теги: ', ', ', ''); ?>  

Не найдено

К сожалению, по Вашему запросу ничего не найдено.

Выделением показал свои модификации файла темы. Как видно, в случае ответа на AJAX запрос мы отдаём токлько свой контейнер “страницы” и оформленные темой анонсы статей. Всё остальное – обрезаем (точнее – просто не генерируем). Безусловно, можно пытаться ту же работу проделать уже на стороне клиента, на jQuery, но тогда чем же это будет быстрее? Мы заставим wordpress генерировать и sidebar, и всё остальное, а потом всё это будем резать? Да и зачем на клиента вешать лишнюю работу? Хотя такой вариант попробую, он, возможно, будет работать без модификации файлов темы, чем и интересен…

А теперь сценарий, который выполнит AJAX запрос при нажатии на ссылку “Следующая страница”:

jQuery(function() {
    jQuery('#content')
        .delegate('', 'onupdate.ajaxReadMore', function(e) {
            jQuery('.page-container').AJAXReadMore({
                ajaxData: {
                    'ajax-read-next-page-mode':'1'
                },
                contentElSelector: ".page-container",
                errorMessage: "Ошибка загрузки следующей страницы.
Попробуйте позднее.", moreElSelector: ".nextpostslink", moreContainerSelector: ".navigation", scrollToSelector: ".navigation" }); }) .trigger('onupdate.ajaxReadMore') ; });

Как видно, этот сценарий использует jQuery плагин AJAXReadMore, который я собрал в предыдущей статье. И понимать этот код следует следующим образом: при обновлении содержимого страницы мы находим контейнеры с классом page-container (именно такой контейнер мы и добавили в файл темы), и находим в нём ссылку с классом nextpostslink. При нажатии на эту ссылку мы будем скроллировать документ в окне браузера до начала нашего контейнера page-container, подгружать следующую страницу, после чего с анимацией удаляем контейнер со ссылкой (navigation) и показываем подгруженное содержание.

Файл плагина wordpress:

Суть проста до безобразия – просто подключаем описанные выше сценарии в “подвал” страницы (да, тема должна поддерживать подвал – wp_footer, как это сделать – писал раньше).

Также мы добавили предикат is_ajax_read_next_page. Он даёт нам возможность определить, готовим ли мы ответ на AJAX запрос или на обычный HTTP GET запрос. И определяет он (предикат) этот факт по наличию URL параметра ‘ajax-read-next-page-mode’, который добавляется в запрос при конфигурировании плагина AJAXReadMore.

Такие вот дела. Работает это решение здесь. В ближайшее время внедрю и к себе на блог, руки не дошли пока что AJAX must go on: читаем в wordpress архивы без перезагрузки страницы (или а ля ВКонтакте с помощью jQuery)