Реализация AJAX пагинации WooCommerce с динамическими фильтрами

Диагностика проблемы: почему стандартная пагинация WooCommerce не подходит для динамических фильтров

По умолчанию WooCommerce использует стандартную пагинацию, которая обновляет страницу целиком при переходе между страницами каталога. При использовании динамических AJAX-фильтров и сортировок это приводит к перезагрузке страницы, потере состояния фильтров и неудобному UX.

Типичные симптомы:

  • Переход по страницам сбрасывает выбранные фильтры.
  • Пагинация не работает после применения AJAX-фильтров.
  • Перезагрузка страницы при смене страницы пагинации.

Пошаговое решение: реализация AJAX пагинации с учетом динамических фильтров

1. Подключение скриптов и локализация данных

Добавьте в файл functions.php темы или в свой плагин следующий код для подключения собственного JS и передачи параметров AJAX:

function my_enqueue_ajax_pagination_scripts() {
    if (is_shop() || is_product_category() || is_product_tag()) {
        wp_enqueue_script('my-ajax-pagination', get_template_directory_uri() . '/js/my-ajax-pagination.js', array('jquery'), '1.0', true);
        wp_localize_script('my-ajax-pagination', 'my_ajax_params', array(
            'ajax_url' => admin_url('admin-ajax.php'),
            'nonce' => wp_create_nonce('my_ajax_nonce')
        ));
    }
}
add_action('wp_enqueue_scripts', 'my_enqueue_ajax_pagination_scripts');

2. Создание AJAX обработчика на PHP

Реализуйте обработчик AJAX запроса, который принимает параметры фильтров и пагинации, формирует WP_Query и возвращает обновленный HTML каталога с пагинацией:

function my_ajax_pagination_handler() {
    check_ajax_referer('my_ajax_nonce', 'nonce');

    $paged = isset($_POST['paged']) ? intval($_POST['paged']) : 1;
    $tax_query = array();

    if (!empty($_POST['filters'])) {
        foreach ($_POST['filters'] as $taxonomy => $terms) {
            $tax_query[] = array(
                'taxonomy' => sanitize_text_field($taxonomy),
                'field'    => 'slug',
                'terms'    => array_map('sanitize_text_field', $terms),
                'operator' => 'IN',
            );
        }
    }

    $args = array(
        'post_type' => 'product',
        'posts_per_page' => 12,
        'paged' => $paged,
        'tax_query' => $tax_query,
    );

    $query = new WP_Query($args);

    ob_start();
    if ($query->have_posts()) {
        woocommerce_product_loop_start();
        while ($query->have_posts()) {
            $query->the_post();
            wc_get_template_part('content', 'product');
        }
        woocommerce_product_loop_end();

        // пагинация
        echo paginate_links(array(
            'total' => $query->max_num_pages,
            'current' => $paged
        ));
    } else {
        echo '<p>Товары не найдены.</p>';
    }
    wp_reset_postdata();

    $html = ob_get_clean();

    wp_send_json_success(array('html' => $html));
}
add_action('wp_ajax_my_ajax_pagination', 'my_ajax_pagination_handler');
add_action('wp_ajax_nopriv_my_ajax_pagination', 'my_ajax_pagination_handler');

3. JavaScript для обработки кликов по пагинации и фильтрам

Создайте файл my-ajax-pagination.js с кодом, который перехватывает клики и отправляет AJAX-запрос:

jQuery(document).ready(function($) {
    function getSelectedFilters() {
        var filters = {};
        $('.widget_layered_nav_filters input:checked').each(function() {
            var taxonomy = $(this).data('taxonomy');
            if (!filters[taxonomy]) {
                filters[taxonomy] = [];
            }
            filters[taxonomy].push($(this).val());
        });
        return filters;
    }

    function loadProducts(paged) {
        var data = {
            action: 'my_ajax_pagination',
            nonce: my_ajax_params.nonce,
            paged: paged || 1,
            filters: getSelectedFilters()
        };

        $.post(my_ajax_params.ajax_url, data, function(response) {
            if (response.success) {
                $('.products-grid').html(response.data.html);
                history.pushState(null, null, '?paged=' + paged);
            }
        });
    }

    // Перехват кликов по пагинации
    $(document).on('click', '.woocommerce-pagination a', function(e) {
        e.preventDefault();
        var href = $(this).attr('href');
        var paged = 1;
        var match = href.match(/[?&]paged=(\d+)/);
        if (match) {
            paged = parseInt(match[1]);
        }
        loadProducts(paged);
    });

    // Перехват изменений фильтров
    $(document).on('change', '.widget_layered_nav_filters input', function() {
        loadProducts(1);
    });

    // Обработка кнопки назад в браузере
    window.onpopstate = function() {
        var urlParams = new URLSearchParams(window.location.search);
        var paged = urlParams.get('paged') || 1;
        loadProducts(paged);
    };
});

Проверка результата после внедрения

  • Откройте страницу магазина или категории.
  • Выберите один или несколько фильтров — список товаров обновится без перезагрузки.
  • Нажмите на номера страниц пагинации — товары сменятся AJAX-запросом, фильтры сохранятся.
  • Проверьте, что URL меняется параметром ?paged= и работает кнопка назад браузера.

Частые ошибки и как их исправить

  • Пагинация ведет на 404 страницу или перезагружает весь сайт: Убедитесь, что в AJAX запросе правильно передается параметр paged и обработчик корректно его использует.
  • Фильтры сбрасываются при переключении страницы: Проверьте, что в JS собираются и отправляются все активные фильтры вместе с номером страницы.
  • Не обновляется URL или не работает кнопка назад: Проверьте реализацию history.pushState и обработку события onpopstate.
  • Пагинация не отображается: Убедитесь, что функция paginate_links вызывается и выводится в AJAX ответе.

Практические советы по производительности и безопасности

  • Используйте nonce для безопасности AJAX-запросов, чтобы предотвратить CSRF.
  • Кешируйте результаты запросов, если фильтры и страница не меняются, для снижения нагрузки на сервер.
  • Проверяйте и фильтруйте входящие данные в AJAX обработчике, особенно параметры фильтров и пагинации.
  • Минимизируйте JS и объединяйте скрипты, чтобы снизить время загрузки.

Сравнение вариантов реализации AJAX пагинации WooCommerce

СпособПлюсыМинусы
Плагин AJAX фильтров и пагинацииБыстрая настройка, готовый UI, поддержка обновленийМожет быть тяжелым, ограничен функционал, платные версии
Самописное решение на AJAX (как в статье)Полный контроль, легковесность, кастомизацияТребует знаний PHP и JS, необходимо тестировать
Переход на бесконечный скролл с AJAXУдобно для UX, плавная загрузка товаровМожет ухудшить SEO, сложнее реализовать фильтры

Добавь в закладки и поделись с друзьями:

⭐⭐⭐⭐⭐
Как исправить неработающую пагинацию при комплексных запросах WP_Query
17.05.2026
Как использовать пагинацию для отображения большого количества комментариев в WordPress
09.05.2026
Как создать собственную пагинацию в WordPress без плагинов
01.11.2025
Как сделать пагинацию для постов по датам в WordPress
15.12.2025
Как исправить неработающую пагинацию при использовании WP_Query в WordPress
24.04.2026
×

AI-плагин от WPShop.ru

анализирует конкурентов

пишет статьи

готовит SEO

генерирует изображения

и еще кое-что...
WPGPT
Плагин, который наполняет ваш сайт WordPress
Узнать больше