115 lines
3.3 KiB
JavaScript
115 lines
3.3 KiB
JavaScript
/**
|
|
* Simplified Mobile Navigation Handler
|
|
* Minimaler Code für maximale Performance
|
|
*/
|
|
class SimpleMobileNav {
|
|
constructor() {
|
|
this.toggle = document.getElementById('mobileMenuToggle');
|
|
this.menu = document.getElementById('mobileMenu');
|
|
this.navbar = document.querySelector('.navbar');
|
|
this.isOpen = false;
|
|
|
|
this.init();
|
|
}
|
|
|
|
init() {
|
|
if (!this.toggle || !this.menu) return;
|
|
|
|
// Toggle Button
|
|
this.toggle.addEventListener('click', (e) => {
|
|
e.stopPropagation();
|
|
this.toggleMenu();
|
|
});
|
|
|
|
// Close on outside click
|
|
document.addEventListener('click', (e) => {
|
|
if (this.isOpen && !this.menu.contains(e.target)) {
|
|
this.closeMenu();
|
|
}
|
|
});
|
|
|
|
// Close on ESC
|
|
document.addEventListener('keydown', (e) => {
|
|
if (e.key === 'Escape' && this.isOpen) {
|
|
this.closeMenu();
|
|
}
|
|
});
|
|
|
|
// Close on resize to desktop
|
|
let resizeTimer;
|
|
window.addEventListener('resize', () => {
|
|
clearTimeout(resizeTimer);
|
|
resizeTimer = setTimeout(() => {
|
|
if (window.innerWidth >= 1024 && this.isOpen) {
|
|
this.closeMenu();
|
|
}
|
|
}, 250);
|
|
});
|
|
|
|
// Simple scroll effect
|
|
let lastScroll = 0;
|
|
window.addEventListener('scroll', () => {
|
|
const currentScroll = window.pageYOffset;
|
|
|
|
// Add/remove scrolled class
|
|
if (currentScroll > 50) {
|
|
this.navbar.classList.add('scrolled');
|
|
} else {
|
|
this.navbar.classList.remove('scrolled');
|
|
}
|
|
|
|
lastScroll = currentScroll;
|
|
}, { passive: true });
|
|
}
|
|
|
|
toggleMenu() {
|
|
this.isOpen ? this.closeMenu() : this.openMenu();
|
|
}
|
|
|
|
openMenu() {
|
|
this.isOpen = true;
|
|
this.menu.classList.remove('hidden');
|
|
|
|
// Force reflow
|
|
this.menu.offsetHeight;
|
|
|
|
this.menu.classList.add('active');
|
|
this.toggle.setAttribute('aria-expanded', 'true');
|
|
|
|
// Update icon
|
|
const path = this.toggle.querySelector('svg path');
|
|
if (path) path.setAttribute('d', 'M6 18L18 6M6 6l12 12');
|
|
|
|
// Prevent body scroll
|
|
document.body.style.overflow = 'hidden';
|
|
}
|
|
|
|
closeMenu() {
|
|
this.isOpen = false;
|
|
this.menu.classList.remove('active');
|
|
this.toggle.setAttribute('aria-expanded', 'false');
|
|
|
|
// Update icon
|
|
const path = this.toggle.querySelector('svg path');
|
|
if (path) path.setAttribute('d', 'M4 6h16M4 12h16M4 18h16');
|
|
|
|
// Restore body scroll
|
|
document.body.style.overflow = '';
|
|
|
|
// Hide after transition
|
|
setTimeout(() => {
|
|
if (!this.isOpen) {
|
|
this.menu.classList.add('hidden');
|
|
}
|
|
}, 200);
|
|
}
|
|
}
|
|
|
|
// Initialize on DOM ready
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
window.mobileNav = new SimpleMobileNav();
|
|
});
|
|
} else {
|
|
window.mobileNav = new SimpleMobileNav();
|
|
}
|