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:
kate522 committed 2026-07-22 11:18:34 +08:00
1 parent b8ee6b6a43
commit 259dbdbe04
28 files changed
+2463 -885

No files matched your search

+1 -1
View File
@@ -276,7 +276,7 @@
top = target.getBoundingClientRect().top + window.pageYOffset;
}
var navFixed = document.querySelector('.site-nav.is-fixed, .site-header.is-fixed');
var navFixed = document.querySelector('body.nav-fixed .header, .navbar.navbar-top');
var headerOffset = navFixed ? (navFixed.offsetHeight + 20) : 0;
top = Math.max(0, top - headerOffset - (extraOffset || 0));
+15 -67
View File
@@ -1,65 +1,10 @@
/**
* AKSRT Dropdown Menus — user, auth, post-meta
* AKSRT Dropdown Menus — post-meta only.
* Header user box uses CSS hover (.navbar-top .sub-menu) per zibll contract.
*/
(function () {
"use strict";
function initUserDropdown() {
var toggle = document.getElementById("user-menu-toggle");
var menu = document.getElementById("user-dropdown");
if (!toggle || !menu) return;
function close() {
menu.classList.remove("is-open");
toggle.setAttribute("aria-expanded", "false");
}
toggle.addEventListener("click", function (e) {
e.stopPropagation();
var open = !menu.classList.contains("is-open");
menu.classList.toggle("is-open", open);
toggle.setAttribute("aria-expanded", open ? "true" : "false");
});
document.addEventListener("click", function (e) {
if (!menu.contains(e.target) && e.target !== toggle) close();
});
document.addEventListener("touchstart", function (e) {
if (!menu.contains(e.target) && e.target !== toggle) close();
}, { passive: true });
document.addEventListener("keydown", function (e) {
if (e.key === "Escape") close();
});
}
function initAuthDropdown() {
var trigger = document.getElementById("nav-auth-trigger");
var container = document.getElementById("nav-auth-dropdown");
if (!trigger || !container) return;
function close() {
container.classList.remove("is-open");
trigger.setAttribute("aria-expanded", "false");
}
trigger.addEventListener("click", function (e) {
e.stopPropagation();
var open = !container.classList.contains("is-open");
container.classList.toggle("is-open", open);
trigger.setAttribute("aria-expanded", open ? "true" : "false");
});
document.addEventListener("click", function (e) {
if (!container.contains(e.target) && e.target !== trigger) close();
});
document.addEventListener("touchstart", function (e) {
if (!container.contains(e.target) && e.target !== trigger) close();
}, { passive: true });
document.addEventListener("keydown", function (e) {
if (e.key === "Escape") close();
});
}
function initPostDropMeta() {
document.querySelectorAll('.post-drop-meta').forEach(function (wrap) {
if (!wrap || wrap.dataset.aksrtDropMetaBound === '1') return;
@@ -80,10 +25,10 @@
document.querySelectorAll('.post-drop-meta.is-open').forEach(function (other) {
if (other !== wrap) {
other.classList.remove('is-open');
var otherTrigger = other.querySelector('.post-drop-meta__toggle');
var otherMenu = other.querySelector('.post-drop-meta__menu');
if (otherTrigger) otherTrigger.setAttribute('aria-expanded', 'false');
if (otherMenu) otherMenu.setAttribute('aria-hidden', 'true');
var t = other.querySelector('.post-drop-meta__toggle');
var m = other.querySelector('.post-drop-meta__menu');
if (t) t.setAttribute('aria-expanded', 'false');
if (m) m.setAttribute('aria-hidden', 'true');
}
});
wrap.classList.toggle('is-open', open);
@@ -94,16 +39,19 @@
document.addEventListener('click', function (e) {
if (!wrap.contains(e.target)) close();
});
document.addEventListener('touchstart', function (e) {
if (!wrap.contains(e.target)) close();
}, { passive: true });
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape') close();
});
});
}
window.AksrtFrontend.register("aksrt-user-dropdown", function () { initUserDropdown(); });
window.AksrtFrontend.register("aksrt-auth-dropdown", function () { initAuthDropdown(); });
window.AksrtFrontend.register("aksrt-post-drop-meta", function () { initPostDropMeta(); });
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === 'function') {
window.AksrtFrontend.register('aksrt-post-drop-meta', function () {
initPostDropMeta();
});
} else if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initPostDropMeta);
} else {
initPostDropMeta();
}
})();
+71 -37
View File
@@ -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();
}
})();
+5 -17
View File
@@ -136,28 +136,16 @@
}
function initNavScrollState() {
var nav = document.querySelector(".site-nav");
var sliderContainer = document.querySelector(".header-components-container");
if (nav && sliderContainer) {
nav.classList.add("nav-transparent");
}
var scrollDownHide = document.body.classList.contains("scroll-down-hide");
// Zibll: hide is CSS on body.scroll-down + header.scroll-down-hide.
// Keep is-scrolled on .header for optional consumers.
var header = document.querySelector(".header");
var ticking = false;
function update() {
ticking = false;
var body = document.body;
if (nav) {
nav.classList.toggle("is-scrolled", body.classList.contains("body-scroll"));
}
if (nav && scrollDownHide) {
if (body.classList.contains("scroll-down")) {
nav.classList.add("is-hidden");
} else {
nav.classList.remove("is-hidden");
}
if (header) {
header.classList.toggle("is-scrolled", body.classList.contains("body-scroll"));
}
}
+1 -1
View File
@@ -525,7 +525,7 @@
* 菜单项超出容器宽度时折叠进「更多」下拉
* ============================================================ */
function initNavOverflow() {
var nav = document.querySelector('.site-nav .nav-menu, .site-nav .primary-nav, .header-nav__menu');
var nav = document.querySelector('.navbar-top .nav.navbar-nav');
if (!nav) return;
// 创建「更多」按钮
+1 -1
View File
@@ -137,7 +137,7 @@
// Numeric badge inside the user dropdown only — never target the pure avatar
// .nav-user__dot.aksrt-notification-badge (no textContent on a dot indicator).
var headerBadge = document.querySelector('.user-dropdown__badge');
var headerBadge = document.querySelector('.aksrt-notification-badge');
if (headerBadge) {
headerBadge.textContent = String(nextUnread);
headerBadge.style.display = nextUnread > 0 ? '' : 'none';
+2 -2
View File
@@ -182,10 +182,10 @@
el.style.transform = 'translateX(100%)';
el.style.opacity = '0';
setTimeout(function () {
el.classList.remove('is-open');
el.style.transform = '';
el.style.opacity = '';
document.body.classList.remove('nav-open');
// Zibll contract: drawer open state lives on body.
document.body.classList.remove('mobile-navbar-show');
}, 200);
} else {
el.style.transition = 'transform 0.2s, opacity 0.2s';
+1 -1
View File
@@ -30,7 +30,7 @@
function siteName() {
return (
metaContent(['meta[property="og:site_name"]']) ||
(document.querySelector('.site-title, .logo-text, .site-nav__logo') || {}).textContent ||
(document.querySelector('.site-title, .logo-text, .navbar-logo') || {}).textContent ||
document.title ||
''
).trim();