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

120 lines
3.7 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 17:08:59 +01:00
menuItems.forEach(item => {
let timeout;
2025-01-09 14:42:38 +01:00
2025-01-14 17:08:59 +01:00
// Öffnen beim Hovern
item.addEventListener('mouseenter', () => {
clearTimeout(timeout);
openMenu(item, true);
2025-01-14 17:08:59 +01:00
});
2025-01-10 14:05:53 +01:00
2025-01-14 17:08:59 +01:00
// Verzögertes Schließen beim Verlassen
item.addEventListener('mouseleave', () => {
timeout = setTimeout(() => closeMenu(item), 500);
});
2025-01-09 14:42:38 +01:00
2025-01-14 17:52:31 +01:00
// Öffnen und Position anpassen beim Klicken
2025-01-14 17:08:59 +01:00
item.addEventListener('click', (e) => {
2025-01-14 17:52:31 +01:00
e.preventDefault(); // Verhindert die Standardaktion
2025-01-14 17:08:59 +01:00
e.stopPropagation(); // Verhindert das Schließen von Menüs bei Klick
if (item.classList.contains('open')) {
closeMenu(item);
} else {
openMenu(item, true);
}
});
});
subMenuItems.forEach(item => {
let timeout;
// Öffnen beim Hovern
item.addEventListener('mouseenter', () => {
clearTimeout(timeout);
openMenu(item, false);
});
// Verzögertes Schließen beim Verlassen
item.addEventListener('mouseleave', () => {
timeout = setTimeout(() => closeMenu(item), 500);
});
2025-01-14 17:52:31 +01:00
// Öffnen und Position anpassen beim Klicken
item.addEventListener('click', (e) => {
2025-01-14 17:52:31 +01:00
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, false);
2025-01-14 17:08:59 +01:00
}
2025-01-09 14:42:38 +01:00
});
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) {
submenu.style.bottom = '100%';
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%';
2025-01-14 17:52:31 +01:00
const prefersBelow = spaceBelow >= spaceAbove;
submenu.style.top = prefersBelow ? '0' : 'auto';
submenu.style.bottom = prefersBelow ? 'auto' : '100%';
}
}
2025-01-14 17:52:31 +01:00
});