homepage.veen.world/app/static/js/navigation.js

119 lines
3.9 KiB
JavaScript
Raw Normal View History

2025-01-09 14:42:38 +01:00
document.addEventListener('DOMContentLoaded', () => {
const menuItems = document.querySelectorAll('.nav-item.dropdown');
const subMenuItems = document.querySelectorAll('.dropdown-submenu');
2025-01-09 14:42:38 +01:00
2025-01-14 19:12:43 +01:00
function addMenuEventListeners(items, isTopLevel) {
items.forEach(item => {
let timeout;
2025-01-14 19:25:07 +01:00
function onMouseEnter() {
2025-01-14 19:12:43 +01:00
clearTimeout(timeout);
openMenu(item, isTopLevel);
refreshEventListeners();
2025-01-14 19:25:07 +01:00
}
function onMouseLeave() {
timeout = setTimeout(() => {
closeMenu(item);
}, 500);
}
// Öffnen beim Hovern
item.addEventListener('mouseenter', onMouseEnter);
2025-01-14 19:12:43 +01:00
// Verzögertes Schließen beim Verlassen
2025-01-14 19:25:07 +01:00
item.addEventListener('mouseleave', onMouseLeave);
2025-01-14 19:12:43 +01:00
// Öffnen und Position anpassen beim Klicken
item.addEventListener('click', (e) => {
e.preventDefault(); // Verhindert die Standardaktion
e.stopPropagation(); // Verhindert das Schließen von Menüs bei Klick
if (item.classList.contains('open')) {
closeMenu(item);
} else {
openMenu(item, isTopLevel);
}
refreshEventListeners();
2025-01-14 19:12:43 +01:00
});
});
2025-01-14 19:12:43 +01:00
}
function refreshEventListeners() {
const updatedMenuItems = document.querySelectorAll('.nav-item.dropdown');
const updatedSubMenuItems = document.querySelectorAll('.dropdown-submenu');
addMenuEventListeners(updatedMenuItems, true);
addMenuEventListeners(updatedSubMenuItems, false);
}
2025-01-14 19:12:43 +01:00
addMenuEventListeners(menuItems, true);
addMenuEventListeners(subMenuItems, false);
2025-01-14 17:08:59 +01:00
// Globale Klick-Listener, um Menüs zu schließen, wenn außerhalb geklickt wird
document.addEventListener('click', () => {
[...menuItems, ...subMenuItems].forEach(item => closeMenu(item));
2025-01-14 17:08:59 +01:00
});
function openMenu(item, isTopLevel) {
2025-01-14 17:08:59 +01:00
item.classList.add('open');
const submenu = item.querySelector('.dropdown-menu');
if (submenu) {
adjustMenuPosition(submenu, item, isTopLevel);
2025-01-14 17:08:59 +01:00
submenu.style.display = 'block';
submenu.style.opacity = '1';
submenu.style.visibility = 'visible';
}
}
function closeMenu(item) {
item.classList.remove('open');
const submenu = item.querySelector('.dropdown-menu');
if (submenu) {
submenu.style.display = 'none';
submenu.style.opacity = '0';
submenu.style.visibility = 'hidden';
}
}
function adjustMenuPosition(submenu, parent, isTopLevel) {
const rect = submenu.getBoundingClientRect();
const parentRect = parent.getBoundingClientRect();
// Platzberechnung
const spaceAbove = parentRect.top;
const spaceBelow = window.innerHeight - parentRect.bottom;
const spaceLeft = parentRect.left;
const spaceRight = window.innerWidth - parentRect.right;
// Standardpositionierung
submenu.style.top = '';
submenu.style.bottom = '';
submenu.style.left = '';
submenu.style.right = '';
if (isTopLevel) {
// Top-Level-Menüs öffnen nur nach oben oder unten
if (spaceBelow < rect.height && spaceAbove > rect.height) {
2025-01-14 19:33:13 +01:00
submenu.style.bottom = `${window.innerHeight - parentRect.bottom - parentRect.height}px`;
2025-01-14 17:52:31 +01:00
submenu.style.top = 'auto';
} else {
2025-01-14 17:52:31 +01:00
submenu.style.top = `${parentRect.height}px`;
submenu.style.bottom = 'auto';
}
} else {
// Submenüs öffnen in die Richtung mit mehr Platz
2025-01-14 17:52:31 +01:00
const prefersRight = spaceRight >= spaceLeft;
submenu.style.left = prefersRight ? '100%' : 'auto';
submenu.style.right = prefersRight ? 'auto' : '100%';
// Öffnen nach oben, wenn unten kein Platz ist
if (spaceBelow < rect.height && spaceAbove > rect.height) {
submenu.style.top = 'auto';
2025-01-14 19:12:43 +01:00
submenu.style.bottom = `${parentRect.bottom - parentRect.top - rect.height}px`; // Höhe des Submenüs wird berücksichtigt
} else {
submenu.style.top = '0';
submenu.style.bottom = 'auto';
}
}
}
2025-01-14 17:52:31 +01:00
});