feat(nav): rewrite top header to zibll 1:1 DOM/CSS/JS contract
Replace hybrid site-nav/drawer shell with zibll navbar-top layouts 1/2/3, body.mobile-navbar-show drawer, wired NavWalker + aksrt_menu_options meta, nav_folding/chevron, VIP switches, and SPA/PHP schema parity. No dual-class compat paths.
This commit is contained in:
1 parent
b8ee6b6a43
commit
259dbdbe04
28 files changed
+2463
-885
No files matched your search
+71
-37
@@ -1,54 +1,88 @@
|
||||
/**
|
||||
* AKSRT Navigation Drawer
|
||||
* AKSRT nav chrome — zibll contract (body.mobile-navbar-show, folding, chevron).
|
||||
* Drawer open/close is handled by aksrt-runtime [data-toggle-class].
|
||||
*/
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function initNavDrawer() {
|
||||
var toggle = document.getElementById("nav-toggle");
|
||||
var drawer = document.getElementById("nav-drawer");
|
||||
var backdrop = document.getElementById("nav-drawer-backdrop");
|
||||
var closeBtn = document.getElementById("nav-drawer-close");
|
||||
if (!toggle || !drawer || !backdrop) return;
|
||||
function appendChevrons() {
|
||||
document.querySelectorAll(".navbar-top li.menu-item-has-children > a").forEach(function (a) {
|
||||
if (a.querySelector(".fa-angle-down")) return;
|
||||
var i = document.createElement("i");
|
||||
i.className = "fa fa-angle-down ml6";
|
||||
i.setAttribute("aria-hidden", "true");
|
||||
a.appendChild(i);
|
||||
});
|
||||
}
|
||||
|
||||
var openIcon = toggle.querySelector(".nav-toggle-open");
|
||||
var closeIcon = toggle.querySelector(".nav-toggle-close");
|
||||
function navFolding() {
|
||||
var collapse = document.querySelector(".navbar-collapse");
|
||||
var nav = document.querySelector(".navbar-nav");
|
||||
if (!collapse || !nav) return;
|
||||
if (window.innerWidth <= 996) return;
|
||||
|
||||
function setOpen(open) {
|
||||
toggle.setAttribute("aria-expanded", open ? "true" : "false");
|
||||
drawer.classList.toggle("is-open", open);
|
||||
backdrop.classList.toggle("is-open", open);
|
||||
drawer.setAttribute("aria-hidden", open ? "false" : "true");
|
||||
backdrop.setAttribute("aria-hidden", open ? "false" : "true");
|
||||
document.body.style.overflow = open ? "hidden" : "";
|
||||
if (openIcon && closeIcon) {
|
||||
openIcon.style.display = open ? "none" : "";
|
||||
closeIcon.style.display = open ? "" : "none";
|
||||
var header = document.querySelector(".header");
|
||||
if (header && header.offsetHeight <= 81) return;
|
||||
|
||||
// Already folded?
|
||||
if (nav.querySelector("li.aksrt-nav-more")) return;
|
||||
|
||||
var surplus = collapse.clientWidth;
|
||||
Array.prototype.forEach.call(collapse.children, function (child) {
|
||||
if (!child.classList.contains("navbar-nav")) {
|
||||
surplus -= child.offsetWidth || 0;
|
||||
}
|
||||
if (open && typeof window.__aksrtCloseSearchPanel === "function") {
|
||||
window.__aksrtCloseSearchPanel();
|
||||
});
|
||||
var headerEl = document.querySelector(".navbar-header");
|
||||
surplus -= (headerEl ? headerEl.offsetWidth : 0) + 40;
|
||||
|
||||
var navsWidth = 66;
|
||||
var foldItems = [];
|
||||
Array.prototype.forEach.call(nav.children, function (li) {
|
||||
navsWidth += li.offsetWidth || 0;
|
||||
if (navsWidth > surplus) {
|
||||
foldItems.push(li);
|
||||
}
|
||||
}
|
||||
|
||||
setOpen(false);
|
||||
|
||||
toggle.addEventListener("click", function () {
|
||||
setOpen(!drawer.classList.contains("is-open"));
|
||||
});
|
||||
backdrop.addEventListener("click", function () {
|
||||
setOpen(false);
|
||||
});
|
||||
if (closeBtn) closeBtn.addEventListener("click", function () {
|
||||
setOpen(false);
|
||||
});
|
||||
if (!foldItems.length) return;
|
||||
|
||||
var more = document.createElement("li");
|
||||
more.className = "menu-item menu-item-has-children aksrt-nav-more";
|
||||
more.innerHTML =
|
||||
'<a href="javascript:void(0);"><i class="fas fa-bars" aria-hidden="true"></i></a><ul class="sub-menu"></ul>';
|
||||
var sub = more.querySelector(".sub-menu");
|
||||
foldItems.forEach(function (li) {
|
||||
sub.appendChild(li);
|
||||
});
|
||||
nav.appendChild(more);
|
||||
}
|
||||
|
||||
function bindDrawerA11y() {
|
||||
// Esc closes mobile nav via body class.
|
||||
document.addEventListener("keydown", function (e) {
|
||||
if (e.key === "Escape" && drawer.classList.contains("is-open")) {
|
||||
setOpen(false);
|
||||
toggle.focus();
|
||||
if (e.key === "Escape" && document.body.classList.contains("mobile-navbar-show")) {
|
||||
document.body.classList.remove("mobile-navbar-show");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
window.AksrtFrontend.register("aksrt-nav-drawer", function () { initNavDrawer(); });
|
||||
function init() {
|
||||
appendChevrons();
|
||||
try {
|
||||
navFolding();
|
||||
} catch (err) {
|
||||
// ignore fold failures
|
||||
}
|
||||
bindDrawerA11y();
|
||||
}
|
||||
|
||||
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === "function") {
|
||||
window.AksrtFrontend.register("aksrt-nav-chrome", function () {
|
||||
init();
|
||||
});
|
||||
} else if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
})();
|
||||
Reference in new issue
Block a user