import navigationHtml from "./navigation.html?raw";
/**
* Bindet das mit Vite gebündelte Navbar-Fragment (navigation.html) ein und
* ersetzt damit den Platzhalter im Header der jeweiligen Seite.
* Aufruf z. B. in main.js: initNavbar('#navbar-placeholder')
*/
export function initNavbar(placeholderSelector = "#navbar-placeholder") {
const placeholder = document.querySelector(placeholderSelector);
if (!placeholder) {
console.warn("Navbar-Platzhalter nicht gefunden:", placeholderSelector);
return;
}
placeholder.outerHTML = navigationHtml; // Platzhalter durch echtes Navbar-Markup ersetzen
setupBehavior();
markCurrentPage();
}
/**
* Richtet alle interaktiven Funktionen der Navbar ein:
* - Mobiles Menü öffnen/schließen per Klick
* - Automatischer Fokus auf ersten Link, wenn per Tastatur geöffnet
* - Escape schließt das Menü und gibt den Fokus zurück
* - Menü schließt sich, wenn der Fokus die Navbar per Tab verlässt
* - Klick außerhalb der Navbar schließt das Menü (Maus/Touch)
*/
export function setupBehavior() {
const navbar = document.querySelector(".navbar");
const toggle = document.querySelector(".navbar__toggle");
const nav = document.querySelector(".navbar__nav");
const menu = document.querySelector(".navbar__menu");
if (!navbar || !toggle || !nav || !menu) return;
let openedViaKeyboard = false;
toggle.addEventListener("keydown", (e) => {
if (e.key === "Enter" || e.key === " ") {
openedViaKeyboard = true;
}
});
toggle.addEventListener("click", () => {
const isOpen = nav.classList.toggle("is-open");
toggle.setAttribute("aria-expanded", String(isOpen));
toggle.setAttribute(
"aria-label",
isOpen ? "Menü schließen" : "Menü öffnen",
);
if (isOpen && openedViaKeyboard) {
const firstLink = menu.querySelector(".navbar__link");
if (firstLink) firstLink.focus();
}
openedViaKeyboard = false;
});
document.addEventListener("keydown", (e) => {
if (e.key === "Escape" && nav.classList.contains("is-open")) {
nav.classList.remove("is-open");
toggle.setAttribute("aria-expanded", "false");
toggle.setAttribute("aria-label", "Menü öffnen");
toggle.focus();
}
});
navbar.addEventListener("focusout", (e) => {
const leavingNavbar = !navbar.contains(e.relatedTarget);
if (leavingNavbar && nav.classList.contains("is-open")) {
nav.classList.remove("is-open");
toggle.setAttribute("aria-expanded", "false");
toggle.setAttribute("aria-label", "Menü öffnen");
}
});
document.addEventListener("click", (e) => {
if (!navbar.contains(e.target) && nav.classList.contains("is-open")) {
nav.classList.remove("is-open");
toggle.setAttribute("aria-expanded", "false");
toggle.setAttribute("aria-label", "Menü öffnen");
}
});
}
/**
* Markiert den Menüpunkt der aktuell geöffneten Seite mit aria-current="page",
* damit er optisch hervorgehoben wird (siehe .navbar__link[aria-current="page"] in der CSS).
*/
export function markCurrentPage() {
const links = document.querySelectorAll(".navbar__link");
const current = window.location.pathname.replace(/\/index\.html$/, "/");
links.forEach((link) => {
if (link.getAttribute("href") === current) {
link.setAttribute("aria-current", "page");
}
});
}
document.addEventListener("DOMContentLoaded", () => initNavbar());