mirror of
https://github.com/kevinveenbirkenbach/homepage.veen.world.git
synced 2025-01-15 19:23:58 +01:00
Optimized logic in which direction menus open
This commit is contained in:
parent
7c51ac6bbc
commit
f017cacebe
@ -1,5 +1,6 @@
|
|||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
const menuItems = document.querySelectorAll('.nav-item.dropdown, .dropdown-submenu');
|
const menuItems = document.querySelectorAll('.nav-item.dropdown');
|
||||||
|
const subMenuItems = document.querySelectorAll('.dropdown-submenu');
|
||||||
|
|
||||||
menuItems.forEach(item => {
|
menuItems.forEach(item => {
|
||||||
let timeout;
|
let timeout;
|
||||||
@ -7,7 +8,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
// Öffnen beim Hovern
|
// Öffnen beim Hovern
|
||||||
item.addEventListener('mouseenter', () => {
|
item.addEventListener('mouseenter', () => {
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
openMenu(item);
|
openMenu(item, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Verzögertes Schließen beim Verlassen
|
// Verzögertes Schließen beim Verlassen
|
||||||
@ -21,20 +22,46 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
if (item.classList.contains('open')) {
|
if (item.classList.contains('open')) {
|
||||||
closeMenu(item);
|
closeMenu(item);
|
||||||
} else {
|
} else {
|
||||||
openMenu(item);
|
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);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Offen lassen beim Klicken
|
||||||
|
item.addEventListener('click', (e) => {
|
||||||
|
e.stopPropagation(); // Verhindert das Schließen von Menüs bei Klick
|
||||||
|
if (item.classList.contains('open')) {
|
||||||
|
closeMenu(item);
|
||||||
|
} else {
|
||||||
|
openMenu(item, false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Globale Klick-Listener, um Menüs zu schließen, wenn außerhalb geklickt wird
|
// Globale Klick-Listener, um Menüs zu schließen, wenn außerhalb geklickt wird
|
||||||
document.addEventListener('click', () => {
|
document.addEventListener('click', () => {
|
||||||
menuItems.forEach(item => closeMenu(item));
|
[...menuItems, ...subMenuItems].forEach(item => closeMenu(item));
|
||||||
});
|
});
|
||||||
|
|
||||||
function openMenu(item) {
|
function openMenu(item, isTopLevel) {
|
||||||
item.classList.add('open');
|
item.classList.add('open');
|
||||||
const submenu = item.querySelector('.dropdown-menu');
|
const submenu = item.querySelector('.dropdown-menu');
|
||||||
if (submenu) {
|
if (submenu) {
|
||||||
|
adjustMenuPosition(submenu, item, isTopLevel);
|
||||||
submenu.style.display = 'block';
|
submenu.style.display = 'block';
|
||||||
submenu.style.opacity = '1';
|
submenu.style.opacity = '1';
|
||||||
submenu.style.visibility = 'visible';
|
submenu.style.visibility = 'visible';
|
||||||
@ -50,4 +77,49 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
submenu.style.visibility = 'hidden';
|
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.top = 'auto';
|
||||||
|
submenu.style.bottom = '100%';
|
||||||
|
} else {
|
||||||
|
submenu.style.top = '100%';
|
||||||
|
submenu.style.bottom = 'auto';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Submenüs öffnen in die Richtung mit mehr Platz
|
||||||
|
if (spaceRight < rect.width && spaceLeft > rect.width) {
|
||||||
|
submenu.style.left = 'auto';
|
||||||
|
submenu.style.right = '100%';
|
||||||
|
} else {
|
||||||
|
submenu.style.left = '100%';
|
||||||
|
submenu.style.right = 'auto';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spaceBelow < rect.height && spaceAbove > rect.height) {
|
||||||
|
submenu.style.top = 'auto';
|
||||||
|
submenu.style.bottom = '100%';
|
||||||
|
} else {
|
||||||
|
submenu.style.top = '0';
|
||||||
|
submenu.style.bottom = 'auto';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
@ -3,7 +3,7 @@
|
|||||||
{% for subitem in subitems %}
|
{% for subitem in subitems %}
|
||||||
{% if subitem.subitems %}
|
{% if subitem.subitems %}
|
||||||
<li class="dropdown-submenu position-relative">
|
<li class="dropdown-submenu position-relative">
|
||||||
<a class="dropdown-item dropdown-toggle" title="{{ subitem.description }}">
|
<a class="dropdown-item dropdown-toggle" href="#" title="{{ subitem.description }}">
|
||||||
{% if subitem.icon is defined and subitem.icon.class is defined %}
|
{% if subitem.icon is defined and subitem.icon.class is defined %}
|
||||||
<i class="{{ subitem.icon.class }}"></i> {{ subitem.name }}
|
<i class="{{ subitem.icon.class }}"></i> {{ subitem.name }}
|
||||||
{% else %}
|
{% else %}
|
||||||
@ -33,6 +33,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
<!-- Navigation Bar -->
|
<!-- Navigation Bar -->
|
||||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
@ -52,7 +53,7 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
<!-- Dropdown Menu -->
|
<!-- Dropdown Menu -->
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown{{ loop.index }}" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown{{ loop.index }}" role="button" data-bs-toggle="dropdown" data-bs-display="dynamic" aria-expanded="false">
|
||||||
{% if item.icon is defined and item.icon.class is defined %}
|
{% if item.icon is defined and item.icon.class is defined %}
|
||||||
<i class="{{ item.icon.class }}"></i> {{ item.name }}
|
<i class="{{ item.icon.class }}"></i> {{ item.name }}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
Loading…
Reference in New Issue
Block a user