Активный пункт меню: класс active на PHP и JavaScript
Как подсветить текущий раздел в меню сайта: сравнение адреса на PHP, вариант с массивом пунктов, решение на JavaScript и как это делается в 1С-Битрикс.
При вёрстке шаблона нужно, чтобы пункт меню текущего раздела был выделен. В статичном HTML класс active ставят руками, а на сайте с общим шаблоном его надо вычислять: страница перезагружается, и класс, добавленный по клику, пропадает.
Вариант 1. PHP: сравниваем адрес страницы
<?php
$current = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$menu = [
'/' => 'Главная',
'/news/' => 'Новости',
'/about/' => 'О сайте',
];
?>
<nav><ul>
<?php foreach ($menu as $link => $title):
$active = $link === '/' ? $current === '/' : strpos($current, $link) === 0; ?>
<li><a href="<?= $link ?>"<?= $active ? ' class="active" aria-current="page"' : '' ?>><?= htmlspecialchars($title) ?></a></li>
<?php endforeach; ?>
</ul></nav>
Пункт активен, если адрес страницы начинается с его ссылки, — поэтому «Новости» подсвечиваются и на странице отдельной новости. Главная сравнивается точно, иначе она была бы активна везде. Атрибут aria-current="page" сообщает экранным дикторам, где находится пользователь.
Вариант 2. Меню с параметром в адресе
Если разделы открываются по параметру (/index.php?page=news):
<?php $page = $_GET['page'] ?? 'index'; ?>
<a href="?page=index"<?= $page === 'index' ? ' class="active"' : '' ?>>Главная</a>
<a href="?page=news"<?= $page === 'news' ? ' class="active"' : '' ?>>Новости</a>
Значение по умолчанию 'index' решает частую проблему: при первом заходе параметра нет и главная не подсвечивалась.
Вариант 3. JavaScript
<script>
document.querySelectorAll('.menu a').forEach(function (link) {
const path = new URL(link.href).pathname;
const here = location.pathname;
if (path === '/' ? here === '/' : here.startsWith(path)) {
link.classList.add('active');
link.setAttribute('aria-current', 'page');
}
});
</script>
Скрипт сравнивает пути, а не полные адреса, поэтому не зависит от домена и протокола — менять код при переезде сайта не придётся. Минус — подсветка появляется после загрузки скрипта, поэтому серверный вариант надёжнее.
В 1С-Битрикс
Компонент bitrix:menu сам отмечает текущий пункт: в шаблоне меню у элемента есть флаг $arItem["SELECTED"]. Достаточно вывести класс по нему.