AJAX загрузка постов в WordPress: кнопка и бесконечный скролл

Использование AJAX для загрузки постов в WordPress представляет собой эффективный подход, позволяющий динамично отображать информацию без необходимости перезагрузки страницы. Эта функция особенно полезна для блогов, новостных агрегаторов, каталогов товаров и других проектов, где пользователи должны быстро и удобно просматривать большое количество записей. С помощью AJAX можно значительно улучшить взаимодействие с сайтом и повысить его визуальную привлекательность.

В данном материале мы рассмотрим два метода реализации подгрузки постов через AJAX в WordPress:

  1. по нажатию кнопки «Показать еще»
  2. автоматически при прокрутке страницы

Чтобы реализовать первый метод, необходимо создать кнопку на странице, которая будет генерировать AJAX-запрос на сервер для получения новых постов. Можно использовать встроенные функции WordPress для обработки запросов, такие как admin-ajax.php. Важно также убедиться, что корректно обрабатывается номер страницы и количество загружаемых постов.

Для второго метода, бесконечного скролла, вам потребуется установить обработчик события прокрутки, который будет отслеживать положение скролла и генерировать AJAX-запрос при достижении определенной точки. Это необходимо, чтобы обеспечить плавность загрузки и удобство для пользователя, когда новые посты автоматически появятся по мере прокрутки вниз.

Не забывайте, что для реализации обоих методов важно использовать правильные хуки и обеспечить безопасность ваших запросов, добавляя необходимые проверки и формы защиты данных.

С помощью этих методов вы сможете создать более интерактивный интерфейс для ваших пользователей и повысить общий уровень пользовательского опыта на вашем сайте.

Загрузка постов по кнопке «Загрузить еще»

Суть первого метода заключается в том, что вместо привычной пагинации WordPress мы добавляем кнопку, и при ее нажатии на текущую страницу загружается дополнительная порция записей.

Поскольку мы будем использовать основной запрос WP_Query, количество постов, которые можно подгружать, можно настроить в административной панели WordPress в разделе Настройки > Чтение.

Добавление кнопки

В тех файлах шаблона, где происходят выводы записей (например, index.php, archive.php или home.php), потребуется внедрить кнопку «Загрузить еще». Важно расположить ее вне цикла вывода записей while.

Обратите внимание на следующий момент: если на странице отображены все записи, кнопку следует скрыть.

 
?>
?> max_num_pages; $page = get_query_var('paged') ? get_query_var('paged') : 1; ?> $page) < ?>
Загрузить еще
?>

Приведенный код иллюстрирует, как вывести кнопку после цикла вывода постов. Строки с 3 по 10 отвечают за отображение постов, а с 16 по 20 – за создание кнопки с дополнительной проверкой. Мы добавили id=»load-more» к кнопке, который потребуется для обработки на стороне JS.

В атрибуте data-page кнопки определяется номер текущей страницы, что необходимо для корректной работы AJAX-загрузки при пагинации.

Создание и подключение JavaScript файла

Создадим новый js файл, содержащий весь необходимый код для AJAX-загрузки постов.

Я создал файл load-posts.js в папке js вашего шаблона. Для корректного подключения используем функцию wp_enqueue_script().

В файл functions.php добавьте следующий фрагмент кода:

add_action('wp_enqueue_scripts', 'enqueue_scripts_load_posts'); function enqueue_scripts_load_posts() < wp_enqueue_script( 'load_posts', get_stylesheet_directory_uri(). '/js/load-posts.js', ['jquery'], null, [ 'in_footer' =>true ] ); >

Если ваш шаблон регулярно обновляется, для внесения таких изменений стоит использовать дочернюю тему.

JavaScript обработчик

Теперь нужно разработать обработчик для клика по кнопке #load-more. Откройте файл load-posts.js и добавьте следующий код:

(function($) < $(document).ready(function() < $('#load-more').on('click', function() < const ajaxurl = '/wp-admin/admin-ajax.php'; let button = $(this); let page = button.data('page'); $.ajax(< url: ajaxurl, type: 'POST', data: < action: 'load_posts', page: page >, beforeSend: function() < button.text('Загрузка.'); >, success: function(response) < if (response.trim() !== '') < $('.articles__list').append(response); button.attr('data-page', page + 1); button.text('Загрузить еще'); >else < button.remove(); >> >); >); >); >)(jQuery)

При нажатии на кнопку выполняется AJAX-запрос для загрузки постов. Если контент загружен, он добавляется в контейнер.articles__list (не забудьте указать свой) и обновляется текущий номер страницы. Если постов для загрузки нет, кнопка исчезает.

В методе beforeSend мы установили промежуточное состояние, при котором текст кнопки изменяется на «Загрузка.».

Настройка AJAX обработки запросов

Чтобы AJAX-запросы работали корректно, необходима обработка на стороне сервера. В файл functions.php добавьте следующий код для регистрации AJAX-действия:

add_action('wp_ajax_load_posts', 'load_more_posts'); add_action('wp_ajax_nopriv_load_posts', 'load_more_posts'); function load_more_posts() { $paged = $_POST['page']; $args = array( 'post_type' => 'post', 'paged' => $paged, 'posts_per_page' => get_option('posts_per_page'), ); $query = new WP_Query($args); if($query->have_posts()) : while($query->have_posts()) : $query->the_post(); get_template_part('template-parts/article'); endwhile; wp_reset_postdata(); else: wp_send_json_error(); endif; wp_die(); } 

Этот код отвечает за обработку AJAX-запросов и загрузку постов на основе текущей страницы. Обратите внимание, что мы используем wp_send_json_error(); для обработки ситуации, когда посты закончились.

Теперь ваша функция загрузки постов через AJAX полностью готова! Итак, на вашем сайте будет удобная возможность загрузки новых записей без перезагрузки страницы.

PHP обработчик

Остался финальный шаг. Нужно создать PHP-обработчик для AJAX-запросов.

Все AJAX-запросы в WordPress, как правило, обрабатываются через файл /wp-admin/admin-ajax.php. Это позволяет легко обрабатывать запросы с использованием специальных хуков wp_ajax_ и wp_ajax_nopriv_.

Откройте файл functions.php и вставьте следующий код:

add_action('wp_ajax_load_posts', 'ajax_load_posts'); add_action('wp_ajax_nopriv_load_posts', 'ajax_load_posts'); function ajax_load_posts() { $paged = isset($_POST['page']) ? intval($_POST['page']) : 1; $query = new WP_Query([ 'post_type' =>'post', 'paged' => $paged, 'post_status' => 'publish' ]); if ($query->have_posts()) { while ($query->have_posts()) : $query->the_post(); get_template_part('template-parts/article'); endwhile; } else { echo ''; } wp_reset_postdata(); wp_die(); }

Поскольку мы работаем с постами, в параметрах WP_Query достаточно указать post_type, post_status и не забудьте указать номер страницы (paged), остальные параметры будут выбраны автоматически.

Важно отметить, что в строке 14 используется функция get_template_part, которая загружает файл для отображения одного поста. Если в вашем шаблоне такой файл отсутствует, и все находится в index.php или archive.php, необходимо будет интегрировать HTML-код прямо в обработчик и использовать буферизацию.

Ещё один способ представить это:

add_action('wp_ajax_load_posts', 'ajax_load_posts'); add_action('wp_ajax_nopriv_load_posts', 'ajax_load_posts'); function ajax_load_posts() { $paged = isset($_POST['page']) ? intval($_POST['page']) : 1; $query = new WP_Query([ 'post_type' =>'post', 'paged' => $paged, 'post_status' => 'publish' ]); ob_start(); // Запуск буфера вывода if ($query->have_posts()) { while ($query->have_posts()) : $query->the_post(); ?> 

Также стоит обратить внимание на то, что при работе с AJAX могут возникать проблемы с кэшированием. Чтобы избежать проблем с обновлением данных, вы можете добавить дополнительные параметры к запросу, например, timestamp или уникальный идентификатор. Это поможет обеспечить актуальность загружаемых постов.

Другой важный момент - обработка ошибок. В вашем AJAX-запросе имеет смысл добавить проверку на случай, если посты не были загружены, и соответствующим образом информировать пользователя, например, выводя сообщение об отсутствии постов.

  • Готово! Теперь можно протестировать загрузку.

AJAX загрузка постов при скролле

Теперь создадим бесконечный скролл для страницы с записями. Этот скролл останется бесконечным до тех пор, пока не загрузятся все записи 🙂

Кнопка больше не нужна, вместо неё добавим специальный невидимый блок-якорь, который будет запускать автоматическую загрузку записей при прокрутке к нему.

Многочисленные реализации бесконечного скролла в WordPress предполагают движение до самого низа страницы, однако этот метод может не сработать, если за блоком с записями следуют другие элементы. В этой ситуации подходит способ, который я буду описывать далее.

HTML-разметка


max_num_pages; $page = get_query_var('paged') ? get_query_var('paged') : 1; ?>

Важно отметить, что вместо кнопки мы используем блок #ajax-load-trigger. В его data-параметрах указываем текущий номер страницы и максимальное количество страниц.

PHP-обработчик

Код на PHP остается таким же, как и в предыдущем варианте. Просто скопируйте его в functions.php. Для обработки AJAX-запроса используется функция, которая должна возвращать нужные записи в формате HTML. Не забудьте зарегистрировать свой AJAX-хук:


add_action('wp_ajax_load_posts', 'load_more_posts');
add_action('wp_ajax_nopriv_load_posts', 'load_more_posts');
function load_more_posts() {
$paged = $_POST['page'];
$query = new WP_Query(array(
'paged' => $paged,
'post_type' => 'post',
'posts_per_page' => 10, // количество записей на странице
));
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
get_template_part('template-parts/article'); // замените на свой шаблон записи
}
}
wp_reset_postdata();
die();
}

JS-обработчик

Теперь код на JS будет отличаться. Мы воспользуемся API IntersectionObserver, который может отслеживать, пересекает ли один элемент другой элемент или границу видимости окна.

(function ($) {
let $trigger = $('#ajax-load-trigger'),
page = Number($trigger.attr('data-page')),
maxPage = $trigger.attr('data-max-page'),
loading = false;
if ($trigger.length) {
let observeParams = {
rootMargin: '0px',
threshold: 1.0,
};
let ajaxTriggerLoad = function (entries, observer) {
entries.forEach(function (entry) {
if (entry.isIntersecting && !loading) {
const ajaxurl = '/wp-admin/admin-ajax.php';
loading = true;
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'load_posts',
page: page + 1,
},
beforeSend: function () {
$trigger.text('Загрузка.');
},
success: function (response) {
if (response.trim() !== '') {
$('.articles__list').append(response);
page++;
loading = false;
if (page == maxPage) {
observer.unobserve($trigger[0]);
$trigger.remove();
}
} else {
loading = false; // если ничего не пришло, активируем загрузку
}
},
});
}
});
};
let observerAjaxTriggerLoad = new IntersectionObserver(ajaxTriggerLoad, observeParams);
observerAjaxTriggerLoad.observe($trigger[0]);
}
})(jQuery)

IntersectionObserver наблюдает за нашим элементом-якорем #ajax-load-trigger. Как только он становится видимым в нижней части экрана, инициируется AJAX-загрузка постов, и появляется временный текст «Загрузка.».

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

Добавьте данный код в файл load-posts.js, который мы создали ранее, сохраните все изменения и протестируйте, как это работает.

Если все выполнено согласно инструкции, всё должно функционировать корректно. Если возникнут сложности или вопросы, не стесняйтесь обращаться в комментариях.

Дополнительно, рассмотрите возможность оптимизации загрузки изображений в постах, используя отложенную загрузку (lazy loading). Это может значительно улучшить производительность вашей страницы и пользовательский опыт, особенно при большом количестве статей и изображений на одной странице.

Также полезно добавить индикатор загрузки или анимации, чтобы пользователи понимали, что данные подгружаются. Это улучшит визуальное восприятие взаимодействия с сайтом.

Оставьте комментарий