fix navigation

This commit is contained in:
Tobias Brunner 2025-07-16 16:52:48 +02:00
parent 6f39f73522
commit 529fc9148a
Signed by: tobru
SSH key fingerprint: SHA256:kOXg1R6c11XW3/Pt9dbLdQvOJGFAy+B2K6v6PtRWBGQ
2 changed files with 104 additions and 13 deletions

View file

@ -0,0 +1,96 @@
document.addEventListener('DOMContentLoaded', function () {
// Mobile navigation toggle functionality
const navToggle = document.getElementById('navToggle');
const navMenu = document.getElementById('navMenu');
const headerNav = document.getElementById('headerNav');
const topLine = document.getElementById('topLine');
const middleLine = document.getElementById('middleLine');
const bottomLine = document.getElementById('bottomLine');
let isMenuOpen = false;
// Toggle mobile menu
navToggle.addEventListener('click', function () {
isMenuOpen = !isMenuOpen;
// Toggle menu visibility classes
if (isMenuOpen) {
navMenu.classList.remove('nav__menu-hidden');
navMenu.classList.add('nav__menu-active');
navToggle.setAttribute('aria-expanded', 'true');
// Animate hamburger to X
topLine.classList.add('svg-line-top');
middleLine.classList.add('svg-line-center');
bottomLine.classList.add('svg-line-bottom');
} else {
navMenu.classList.remove('nav__menu-active');
navMenu.classList.add('nav__menu-hidden');
navToggle.setAttribute('aria-expanded', 'false');
// Animate X back to hamburger
topLine.classList.remove('svg-line-top');
middleLine.classList.remove('svg-line-center');
bottomLine.classList.remove('svg-line-bottom');
}
});
// Close menu when clicking on menu items (mobile)
const menuItems = navMenu.querySelectorAll('.menu__item-link');
menuItems.forEach(function (item) {
item.addEventListener('click', function () {
if (window.innerWidth < 992 && isMenuOpen) {
// Trigger the toggle to close menu
navToggle.click();
}
});
});
// Header scroll behavior
let isAtTop = true;
function handleScroll() {
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
const newAtTop = scrollTop <= 200;
if (newAtTop !== isAtTop) {
isAtTop = newAtTop;
if (isAtTop) {
headerNav.classList.remove('header-nav--fixed');
headerNav.classList.add('header-nav--top');
} else {
headerNav.classList.remove('header-nav--top');
headerNav.classList.add('header-nav--fixed');
}
}
}
// Throttle scroll events for better performance
let scrollThrottle = false;
window.addEventListener('scroll', function () {
if (!scrollThrottle) {
requestAnimationFrame(function () {
handleScroll();
scrollThrottle = false;
});
scrollThrottle = true;
}
});
// Handle window resize to ensure proper menu state
window.addEventListener('resize', function () {
if (window.innerWidth >= 992 && isMenuOpen) {
// Reset menu state on desktop
isMenuOpen = false;
navMenu.classList.remove('nav__menu-active');
navMenu.classList.add('nav__menu-hidden');
navToggle.setAttribute('aria-expanded', 'false');
// Reset hamburger animation
topLine.classList.remove('svg-line-top');
middleLine.classList.remove('svg-line-center');
bottomLine.classList.remove('svg-line-bottom');
}
});
});

View file

@ -23,9 +23,9 @@
<script defer data-api="/api/event" data-domain="servala.com" src="/js/script.js"></script>
{% endif %}
<script defer src="{% static "js/htmx204.min.js" %}"></script>
<script defer src="{% static "js/alpine-collapse.min.js" %}"></script>
<script defer src="{% static "js/bootstrap.bundle.min.js" %}"></script>
<script defer src="{% static "js/servala-addons.js" %}"></script>
<script defer src="{% static "js/nav.js" %}"></script>
{% block extra_js %}{% endblock %}
</head>
<body>
@ -40,9 +40,8 @@
</div>
</div>
<header x-data="{sideNav: false, atTop: true}" class="site-header position-relative">
<div class="header-nav" :class="{ 'header-nav--top': atTop, 'header-nav--fixed': !atTop }"
x-on:scroll.window="atTop = (window.pageYOffset > 200) ? false : true;">
<header class="site-header position-relative">
<div class="header-nav header-nav--top" id="headerNav">
<div class="container-xl mx-auto px-3 px-lg-0 position-relative">
<div class="nav__wrapper d-flex justify-content-between align-items-center">
<div class="nav__brand logo">
@ -50,7 +49,7 @@
<img src="{% static "img/header-logo.png" %}" alt="Servala Logo" width="191" height="43">
</a>
</div>
<div x-cloak class="nav__menu" :class="sideNav ? 'nav__menu-active' : 'nav__menu-hidden'">
<div class="nav__menu nav__menu-hidden" id="navMenu">
<nav class="navbar d-lg-flex justify-content-lg-end align-items-lg-center">
<ul class="navbar__menu menu mr-lg-27">
<li class="menu__item"><a class="menu__item-link" href="{% url 'services:homepage' %}">Home</a></li>
@ -66,15 +65,11 @@
</nav>
</div>
<div class="nav__toggle">
<button @click="sideNav = !sideNav" name="menu" class="nav__button" role="button">
<button id="navToggle" name="menu" class="nav__button" role="button" aria-expanded="false" aria-controls="navMenu">
<svg class="nav__button-svg" width="22" height="24">
<line class="button-svg__line" :class="{ 'svg-line-top': sideNav === true }" id="top" x1="0" x2="22"
y1="6" y2="6"></line>
<line class="button-svg__line" :class="{ 'svg-line-center': sideNav === true }" id="middle" x1="0"
x2="22" y1="12" y2="12">
</line>
<line class="button-svg__line" :class="{ 'svg-line-bottom': sideNav === true }" id="bottom" x1="0"
x2="22" y1="18" y2="18"></line>
<line class="button-svg__line" id="topLine" x1="0" x2="22" y1="6" y2="6"></line>
<line class="button-svg__line" id="middleLine" x1="0" x2="22" y1="12" y2="12"></line>
<line class="button-svg__line" id="bottomLine" x1="0" x2="22" y1="18" y2="18"></line>
</svg>
</button>
</div>