mirror of
				https://github.com/kevinveenbirkenbach/homepage.veen.world.git
				synced 2025-10-31 15:39:02 +00:00 
			
		
		
		
	Optimized logic in which direction menus open
This commit is contained in:
		| @@ -1,5 +1,6 @@ | ||||
| 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 => { | ||||
|     let timeout; | ||||
| @@ -7,7 +8,7 @@ document.addEventListener('DOMContentLoaded', () => { | ||||
|     // Öffnen beim Hovern | ||||
|     item.addEventListener('mouseenter', () => { | ||||
|       clearTimeout(timeout); | ||||
|       openMenu(item); | ||||
|       openMenu(item, true); | ||||
|     }); | ||||
|  | ||||
|     // Verzögertes Schließen beim Verlassen | ||||
| @@ -21,20 +22,46 @@ document.addEventListener('DOMContentLoaded', () => { | ||||
|       if (item.classList.contains('open')) { | ||||
|         closeMenu(item); | ||||
|       } 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 | ||||
|   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'); | ||||
|     const submenu = item.querySelector('.dropdown-menu'); | ||||
|     if (submenu) { | ||||
|       adjustMenuPosition(submenu, item, isTopLevel); | ||||
|       submenu.style.display = 'block'; | ||||
|       submenu.style.opacity = '1'; | ||||
|       submenu.style.visibility = 'visible'; | ||||
| @@ -50,4 +77,49 @@ document.addEventListener('DOMContentLoaded', () => { | ||||
|       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 %} | ||||
|         {% if subitem.subitems %} | ||||
|             <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 %} | ||||
|                         <i class="{{ subitem.icon.class }}"></i> {{ subitem.name }} | ||||
|                     {% else %} | ||||
| @@ -33,6 +33,7 @@ | ||||
|         {% endif %} | ||||
|     {% endfor %} | ||||
| {% endmacro %} | ||||
|  | ||||
| <!-- Navigation Bar --> | ||||
| <nav class="navbar navbar-expand-lg navbar-light bg-light"> | ||||
|     <div class="container-fluid"> | ||||
| @@ -52,7 +53,7 @@ | ||||
|                     {% else %} | ||||
|                         <!-- Dropdown Menu --> | ||||
|                         <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 %} | ||||
|                                     <i class="{{ item.icon.class }}"></i> {{ item.name }} | ||||
|                                 {% else %} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user