Added IDs to navigation links Added script to hide expertise and contact links on non-index pages Kept the Start link visible on all pages to return to homepage In components.js: Fixed the COMPONENTS_LOADED_EVENT declaration to prevent duplicate declaration error Added condition to only enable scroll behavior on index page Kept component loading logic but made it more robust
103 lines
3.9 KiB
JavaScript
103 lines
3.9 KiB
JavaScript
// Custom event for when components are fully loaded
|
|
const COMPONENTS_LOADED_EVENT = new Event('componentsLoaded');
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Helper function to handle component loading
|
|
async function loadComponent(url, insertPosition) {
|
|
try {
|
|
const response = await fetch(url);
|
|
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
|
|
const data = await response.text();
|
|
document.body.insertAdjacentHTML(insertPosition, data);
|
|
|
|
// After header is loaded, initialize its event listeners
|
|
if (url.includes('header.html')) {
|
|
initializeHeader();
|
|
}
|
|
return true;
|
|
} catch (error) {
|
|
console.warn(`Failed to load component from ${url}:`, error);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Load components with error handling
|
|
Promise.all([
|
|
loadComponent('components/header.html', 'afterbegin'),
|
|
loadComponent('components/footer.html', 'beforeend')
|
|
]).then(results => {
|
|
if (results.every(Boolean)) {
|
|
// Dispatch custom event when all components are loaded
|
|
document.dispatchEvent(COMPONENTS_LOADED_EVENT);
|
|
}
|
|
}).catch(error => {
|
|
console.warn('Error loading components:', error);
|
|
});
|
|
|
|
// Initialize header functionality after it's loaded
|
|
function initializeHeader() {
|
|
const header = document.querySelector('header');
|
|
if (!header) return;
|
|
|
|
const mobileMenuToggle = header.querySelector('.mobile-menu-toggle');
|
|
const navMenu = header.querySelector('.nav-menu');
|
|
|
|
// Mobile menu toggle
|
|
if (mobileMenuToggle && navMenu) {
|
|
mobileMenuToggle.addEventListener('click', () => {
|
|
navMenu.classList.toggle('active');
|
|
const menuIcon = mobileMenuToggle.querySelector('i');
|
|
if (menuIcon) {
|
|
menuIcon.className = navMenu.classList.contains('active')
|
|
? 'fas fa-times'
|
|
: 'fas fa-bars';
|
|
}
|
|
});
|
|
|
|
// Close menu when clicking outside
|
|
document.addEventListener('click', (e) => {
|
|
if (navMenu.classList.contains('active') &&
|
|
!e.target.closest('.nav-menu') &&
|
|
!e.target.closest('.mobile-menu-toggle')) {
|
|
navMenu.classList.remove('active');
|
|
const menuIcon = mobileMenuToggle.querySelector('i');
|
|
if (menuIcon) {
|
|
menuIcon.className = 'fas fa-bars';
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// Scroll behavior - only enable on index page
|
|
if (window.location.pathname === '/' || window.location.pathname === '/index.html') {
|
|
let lastScrollTop = 0;
|
|
let scrollTimeout;
|
|
|
|
window.addEventListener('scroll', () => {
|
|
if (scrollTimeout) {
|
|
window.cancelAnimationFrame(scrollTimeout);
|
|
}
|
|
|
|
scrollTimeout = window.requestAnimationFrame(() => {
|
|
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
|
|
|
// Don't hide header when near top of page
|
|
if (scrollTop < 100) {
|
|
header.style.transform = 'translateY(0)';
|
|
return;
|
|
}
|
|
|
|
// Hide header on scroll down, show on scroll up
|
|
if (scrollTop > lastScrollTop) {
|
|
header.style.transform = 'translateY(-100%)';
|
|
} else {
|
|
header.style.transform = 'translateY(0)';
|
|
}
|
|
|
|
lastScrollTop = scrollTop;
|
|
});
|
|
}, { passive: true });
|
|
}
|
|
}
|
|
});
|