Диагностика проблемы: почему стандартное обновление корзины WooCommerce неудобно
В стандартной установке WooCommerce при изменении количества товаров в корзине или удалении товара страница корзины перезагружается. Это ухудшает пользовательский опыт, особенно на мобильных устройствах, и замедляет процесс оформления заказа. Вопрос: как реализовать обновление корзины без полной перезагрузки страницы? WooCommerce предлагает встроенный WC AJAX, но его возможности и правильная реализация часто вызывают вопросы.
Как работает WC AJAX в WooCommerce
WC AJAX — это набор AJAX-обработчиков WooCommerce, которые позволяют обновлять отдельные части страницы без полной перезагрузки. Например, добавление товара в корзину через AJAX происходит по умолчанию на странице каталога. Однако корзина и её элементы (количество, удаление) требуют дополнительной настройки.
Основные AJAX-эндпоинты WooCommerce:
wc-ajax=add_to_cart— добавление товара;wc-ajax=get_refreshed_fragments— обновление фрагментов корзины;wc-ajax=remove_from_cart— удаление товара (не всегда реализован по умолчанию);
Пошаговое решение: настройка динамического обновления корзины
1. Подключение скриптов WooCommerce AJAX
Убедитесь, что на странице корзины подключен скрипт wc-cart-fragments — он отвечает за обновление мини-корзины и её фрагментов.
function enqueue_wc_ajax_scripts() {
if (is_cart() || is_checkout()) {
wp_enqueue_script('wc-cart-fragments');
}
}
add_action('wp_enqueue_scripts', 'enqueue_wc_ajax_scripts');2. Добавление AJAX-обработчиков для изменения количества и удаления товаров
WooCommerce по умолчанию не обновляет корзину AJAX при изменении количества товара или удалении. Добавим собственный AJAX-запрос:
jQuery(function($) {
// Обработка изменения количества
$('form.woocommerce-cart-form').on('change', 'input.qty', function() {
var $form = $(this).closest('form');
$.ajax({
url: wc_cart_params.wc_ajax_url.toString().replace('%%endpoint%%', 'update_cart'),
type: 'POST',
data: $form.serialize(),
success: function(response) {
if(response.fragments) {
$.each(response.fragments, function(key, value) {
$(key).replaceWith(value);
});
}
}
});
});
// Обработка удаления товара по ссылке
$('.woocommerce-cart-form').on('click', '.remove', function(e) {
e.preventDefault();
var href = $(this).attr('href');
$.ajax({
url: href,
type: 'GET',
success: function() {
$.ajax({
url: wc_cart_params.wc_ajax_url.toString().replace('%%endpoint%%', 'get_refreshed_fragments'),
type: 'POST',
success: function(response) {
if(response.fragments) {
$.each(response.fragments, function(key, value) {
$(key).replaceWith(value);
});
}
}
});
}
});
});
});Обратите внимание, что для удаления мы отправляем AJAX-запрос по ссылке удаления, а затем обновляем фрагменты корзины.
3. Создание PHP-обработчика AJAX-запроса обновления корзины
В functions.php добавим обработчик для endpoint update_cart:
add_action('wc_ajax_update_cart', 'custom_ajax_update_cart');
add_action('wc_ajax_nopriv_update_cart', 'custom_ajax_update_cart');
function custom_ajax_update_cart() {
if (!isset($_POST['cart'])) {
wp_send_json_error('Отсутствуют данные корзины');
}
foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) {
if (isset($_POST['cart'][$cart_item_key]['qty'])) {
$qty = intval($_POST['cart'][$cart_item_key]['qty']);
WC()->cart->set_quantity($cart_item_key, $qty, true);
}
}
WC()->cart->calculate_totals();
WC()->cart->maybe_set_cart_cookies();
ob_start();
woocommerce_cart_totals();
$cart_totals = ob_get_clean();
ob_start();
woocommerce_cart_contents();
$cart_contents = ob_get_clean();
wp_send_json_success(array(
'fragments' => array(
'.shop_table.cart' => $cart_contents,
'.cart_totals' => $cart_totals
)
));
}Проверка результата после внедрения
1. Перейдите на страницу корзины.
2. Измените количество товара в поле input.qty. Страница не должна перезагружаться, а сумма и содержимое корзины обновится.
3. Нажмите на кнопку удаления товара. Запрос должен выполниться без перезагрузки, и товар исчезнет из корзины.
4. Откройте консоль браузера (F12) и убедитесь, что нет ошибок JavaScript и AJAX-запросы выполняются с статусом 200.
Частые ошибки и способы их исправления
- AJAX-запросы не выполняются: проверьте, подключен ли
wc-cart-fragmentsи правильна ли локализацияwc_cart_params. - Обработчик PHP не вызывается: убедитесь, что хук
wc_ajax_update_cartдобавлен правильно и нет конфликтов с другими плагинами. - Фрагменты корзины не обновляются: проверьте, что ответы AJAX содержат ключ
fragmentsс правильными селекторами и HTML. - Изменения количества не сохраняются: проверьте логику обновления количества в PHP-функции и передачу данных из формы.
Практические советы по безопасности и производительности
- Всегда проверяйте права пользователя при обработке AJAX-запросов, особенно если корзина используется в закрытых зонах.
- Используйте
wp_verify_nonceдля защиты AJAX-запросов от CSRF. - Минимизируйте объем возвращаемых фрагментов, чтобы не перегружать сеть и клиент.
- Кэшируйте статику и используйте оптимизированные скрипты WooCommerce для уменьшения нагрузки.
Сравнение вариантов реализации динамического обновления корзины
| Способ | Плюсы | Минусы |
|---|---|---|
Использование готового скрипта wc-cart-fragments | Простота, встроено в WooCommerce, поддержка обновления мини-корзины | Не обновляет корзину на странице без доработок |
| Кастомный AJAX обработчик для обновления корзины | Полный контроль над обновлением, без перезагрузки | Требует дополнительной разработки и тестирования |
| Плагины сторонних разработчиков | Быстрая настройка, дополнительные функции | Возможны конфликты, нагрузка, зависимость |