Динамическое меню — одна из востребованных функций современных сайтов на WordPress. Оно позволяет загружать пункты меню без перезагрузки страницы, улучшая пользовательский опыт и снижая нагрузку на сервер. В этой статье мы подробно разберем, как создать кастомное динамическое меню с использованием AJAX, чтобы при клике на категорию подгружались дочерние элементы, а также рассмотрим примеры кода и рекомендации по оптимизации.
Почему стоит использовать динамическое меню с AJAX в WordPress
Стандартные меню WordPress формируются при загрузке страницы и не обновляются динамически без перезагрузки. Это ограничивает UX при работе с большим количеством пунктов или вложенных уровней. Использование AJAX позволяет:
- Загружать пункты меню по запросу, экономя ресурсы
- Обеспечивать плавный интерфейс без перезагрузки
- Делать меню адаптивным и интерактивным
- Упрощать навигацию на сайтах с большим количеством категорий и разделов
Реализовать такую логику можно как через собственный плагин, так и в теме. Ниже приведен пример, который легко адаптировать под конкретные задачи.
Подготовка кастомного меню и AJAX-обработчика в WordPress
Для начала создадим кастомное меню в админке WordPress. Далее настроим AJAX-запросы, которые будут подгружать дочерние пункты.
Регистрация AJAX-обработчика
Добавьте в functions.php вашей темы или в плагин следующий код:
function wpabout_ajax_load_menu_items() {
// Проверяем nonce для безопасности
check_ajax_referer('wpabout_ajax_nonce', 'security');
$parent_id = isset($_POST['parent_id']) ? intval($_POST['parent_id']) : 0;
// Получаем пункты меню, у которых родителем является $parent_id
$menu_locations = get_nav_menu_locations();
$menu = wp_get_nav_menu_object($menu_locations['primary']); // замените 'primary' на свой локационный ключ
$menu_items = wp_get_nav_menu_items($menu->term_id);
$child_items = array_filter($menu_items, function($item) use ($parent_id) {
return intval($item->menu_item_parent) === $parent_id;
});
if (empty($child_items)) {
wp_send_json_error('Нет дочерних элементов');
}
$response = [];
foreach ($child_items as $item) {
$response[] = [
'title' => $item->title,
'url' => $item->url,
'ID' => $item->ID
];
}
wp_send_json_success($response);
}
add_action('wp_ajax_wpabout_load_menu_items', 'wpabout_ajax_load_menu_items');
add_action('wp_ajax_nopriv_wpabout_load_menu_items', 'wpabout_ajax_load_menu_items');
Здесь мы создаем функцию, которая по AJAX получает дочерние пункты меню по ID родителя и возвращает их в формате JSON.
Подключение скрипта и локализация данных
Чтобы отправлять AJAX-запросы из фронтенда, подключим JS-файл с нужными настройками:
function wpabout_enqueue_scripts() {
wp_enqueue_script('wpabout-menu-ajax', get_template_directory_uri() . '/js/wpabout-menu-ajax.js', ['jquery'], null, true);
wp_localize_script('wpabout-menu-ajax', 'wpabout_ajax_obj', [
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('wpabout_ajax_nonce')
]);
}
add_action('wp_enqueue_scripts', 'wpabout_enqueue_scripts');
Теперь создадим файл wpabout-menu-ajax.js в папке js темы.
JavaScript для динамической загрузки меню по клику
В файле wpabout-menu-ajax.js реализуем обработчик кликов по пунктам меню, который будет отправлять AJAX-запрос и подгружать дочерние элементы:
jQuery(document).ready(function($) {
// Обработчик клика на пункт меню с классом .has-children
$('.menu-item.has-children > a').on('click', function(e) {
e.preventDefault();
var parentId = $(this).parent().attr('id').replace('menu-item-', '');
var submenu = $(this).siblings('.sub-menu');
// Проверяем, есть ли уже подменю
if (submenu.length) {
submenu.toggle();
return;
}
// Отправка AJAX-запроса
$.ajax({
url: wpabout_ajax_obj.ajax_url,
type: 'POST',
dataType: 'json',
data: {
action: 'wpabout_load_menu_items',
security: wpabout_ajax_obj.nonce,
parent_id: parentId
},
success: function(response) {
if (response.success) {
var items = response.data;
var ul = $('<ul/>', {class: 'sub-menu'});
items.forEach(function(item) {
var li = $('<li/>', {class: 'menu-item', id: 'menu-item-' + item.ID});
var a = $('<a/>', {href: item.url, text: item.title});
li.append(a);
ul.append(li);
});
$(e.target).parent().append(ul);
} else {
alert('Подменю не найдено');
}
},
error: function() {
alert('Ошибка загрузки меню');
}
});
});
});
Этот скрипт навешивает обработчик на пункты меню с дочерними элементами, подгружая их только при необходимости.
Дополнительные рекомендации по оптимизации и безопасности
При внедрении AJAX меню стоит учитывать несколько важных аспектов:
- Безопасность: Всегда проверяйте nonce в AJAX-обработчиках, чтобы предотвратить CSRF-атаки.
- Кэширование: Для сайтов с высокой нагрузкой разумно кэшировать результаты AJAX-запросов, например, используя Transients API.
- Удобство пользователя: Добавляйте индикаторы загрузки при запросах, чтобы пользователь видел процесс.
- Адаптивность: Убедитесь, что меню корректно работает на мобильных устройствах и с клавиатурной навигацией.
- SEO: Помните, что динамически подгружаемое меню может быть не полностью индексировано поисковиками, поэтому базовое меню должно быть доступно без JS.
Использование плагинов для динамического меню
Если вы не хотите кодировать с нуля, можно использовать готовые решения. Например, плагин Max Mega Menu поддерживает AJAX для подгрузки элементов. Но собственный код дает больше гибкости.
Для улучшения производительности можно использовать Clearfy Pro, который оптимизирует работу скриптов и уменьшает нагрузку на сайт.
Итоги и применение на практике
Динамическое меню с поддержкой AJAX — отличный способ сделать навигацию на сайте более удобной и современной. Мы разобрали создание AJAX-обработчика в WordPress, подключение скрипта и пример фронтенд-кода. Используйте этот подход для проектов с большим количеством вложенных меню, каталоги, магазины и информационные порталы.