1// Header component loader 2(function() { 3 function loadHeader() { 4 const headerPlaceholder = document.getElementById('header-placeholder'); 5 if (!headerPlaceholder) return; 6 7 fetch('/components/header.html') 8 .then(response => { 9 if (!response.ok) { 10 throw new Error('Failed to load header'); 11 } 12 return response.text(); 13 }) 14 .then(html => { 15 headerPlaceholder.innerHTML = html; 16 17 // Initialize mobile menu functionality 18 initMobileMenu(); 19 20 // Set active link based on current page 21 setActiveLink(); 22 23 // Initialize header scroll effect 24 initHeaderScroll(); 25 }) 26 .catch(error => { 27 console.error('Error loading header:', error); 28 }); 29 } 30 31 function initMobileMenu() { 32 const menuButton = document.querySelector('.menu__button'); 33 const menuCross = document.querySelector('.mobile__menu--cross'); 34 const mobileMenu = document.querySelector('.mobile__menu'); 35 36 if (menuButton && mobileMenu) { 37 menuButton.addEventListener('click', function() { 38 mobileMenu.classList.add('active'); 39 }); 40 } 41 42 if (menuCross && mobileMenu) { 43 menuCross.addEventListener('click', function() { 44 mobileMenu.classList.remove('active'); 45 }); 46 } 47 } 48 49 function setActiveLink() { 50 const currentPath = window.location.pathname; 51 const navLinks = document.querySelectorAll('.header__nav--link'); 52 53 // Clean current path 54 const currentPathClean = currentPath.replace(/^\//, '').replace(/\/$/, '') || 'index'; 55 56 navLinks.forEach(link => { 57 const href = link.getAttribute('href'); 58 if (!href) return; 59 60 // Skip external links (http/https) - they should never be active 61 if (href.startsWith('http://') || href.startsWith('https://')) { 62 return; 63 } 64 65 // Only check internal links (starting with /) 66 if (href.startsWith('/')) { 67 const linkPath = href.replace(/^\//, '').replace(/\/$/, ''); 68 69 // Exact match for internal pages 70 if (currentPathClean === linkPath) { 71 link.classList.add('active'); 72 } 73 // Special case: root path should match empty linkPath 74 else if (currentPathClean === 'index' && linkPath === '') { 75 // Don't mark any link as active on homepage 76 } 77 } 78 }); 79 } 80 81 function initHeaderScroll() { 82 const header = document.querySelector('.header'); 83 if (!header) return; 84 85 window.addEventListener('scroll', function() { 86 if (window.scrollY > 50) { 87 header.classList.add('header--scrolled'); 88 } else { 89 header.classList.remove('header--scrolled'); 90 } 91 }); 92 } 93 94 // Load header when DOM is ready 95 if (document.readyState === 'loading') { 96 document.addEventListener('DOMContentLoaded', loadHeader); 97 } else { 98 loadHeader(); 99 } 100})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.