/** * Адаптивное меню шапки: выезжающая панель при ширине viewport < 920px. * Закрытие по клику на подложку, Escape, переходу на другую страницу и при расширении окна. * * Автор: Сергей Антропов * Сайт: https://devops.org.ru */ (function () { "use strict"; var MQ = "(max-width: 919px)"; var OPEN_CLASS = "top-nav-actions--open"; var BODY_CLASS = "nav-mobile-open"; var TOGGLE_OPEN_CLASS = "nav-menu-toggle--open"; function mqMobile() { return window.matchMedia(MQ).matches; } /** Закрывает выпадающее меню API (дублирует логику из base.html, чтобы не дублировать DOM-события). */ function closeApiDropdown() { var dd = document.querySelector(".nav-dropdown"); if (!dd) return; var btn = document.getElementById("nav-api-trigger"); var menu = document.getElementById("nav-api-menu"); dd.classList.remove("nav-dropdown--open"); if (btn) btn.setAttribute("aria-expanded", "false"); if (menu) menu.setAttribute("hidden", ""); } function getEls() { return { toggle: document.getElementById("nav-menu-toggle"), drawer: document.getElementById("top-nav-drawer"), backdrop: document.getElementById("nav-menu-backdrop"), }; } function setOpen(open) { var els = getEls(); if (!els.toggle || !els.drawer || !els.backdrop) return; els.toggle.setAttribute("aria-expanded", open ? "true" : "false"); els.toggle.setAttribute( "aria-label", open ? "Закрыть меню разделов" : "Открыть меню разделов", ); els.toggle.classList.toggle(TOGGLE_OPEN_CLASS, open); els.drawer.classList.toggle(OPEN_CLASS, open); if (open) { closeApiDropdown(); els.backdrop.removeAttribute("hidden"); els.backdrop.setAttribute("aria-hidden", "false"); document.body.classList.add(BODY_CLASS); var closeBtn = document.getElementById("nav-drawer-close"); if (closeBtn && mqMobile()) { try { closeBtn.focus(); } catch (e) { /* focus не всегда доступен */ } } } else { els.backdrop.setAttribute("hidden", ""); els.backdrop.setAttribute("aria-hidden", "true"); document.body.classList.remove(BODY_CLASS); closeApiDropdown(); } } function toggle() { var els = getEls(); if (!els.drawer) return; setOpen(!els.drawer.classList.contains(OPEN_CLASS)); } function closeIfMobile() { if (mqMobile()) setOpen(false); } function onResize() { if (!mqMobile()) setOpen(false); } function init() { var els = getEls(); if (!els.toggle || !els.drawer || !els.backdrop) return; els.toggle.addEventListener("click", function (e) { e.stopPropagation(); if (!mqMobile()) return; toggle(); }); els.backdrop.addEventListener("click", function () { closeIfMobile(); }); document.addEventListener("keydown", function (e) { if (e.key === "Escape") closeIfMobile(); }); window.addEventListener("resize", onResize); /* Закрытие при уходе со страницы по ссылке внутри панели */ els.drawer.addEventListener("click", function (e) { var a = e.target.closest("a[href]"); if (!a || !mqMobile()) return; if (a.getAttribute("href") === "#" || a.getAttribute("href") === "") return; if (a.getAttribute("target") === "_blank") return; /* data-open-window открывает новое окно — страница не перезагружается */ if (a.hasAttribute("data-open-window")) return; setOpen(false); }); var closeDrawer = document.getElementById("nav-drawer-close"); if (closeDrawer) { closeDrawer.addEventListener("click", function (e) { e.stopPropagation(); closeIfMobile(); }); } } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", init); } else { init(); } })();