/** * SMRN5001 Static Site JavaScript * Functionality for mobile navigation and interactive features */ (function() { 'use strict'; // Wait for DOM to be ready document.addEventListener('DOMContentLoaded', function() { initMobileNavigation(); initSmoothScrolling(); initActiveNavigation(); initAccessibility(); }); /** * Initialize mobile navigation toggle */ function initMobileNavigation() { const mobileToggle = document.querySelector('.mobile-menu-toggle'); const navMenu = document.querySelector('.nav-menu'); if (!mobileToggle || !navMenu) return; mobileToggle.addEventListener('click', function() { const isActive = navMenu.classList.contains('active'); if (isActive) { navMenu.classList.remove('active'); mobileToggle.setAttribute('aria-expanded', 'false'); mobileToggle.textContent = 'Menu'; } else { navMenu.classList.add('active'); mobileToggle.setAttribute('aria-expanded', 'true'); mobileToggle.textContent = 'Close'; } }); // Close mobile menu when clicking outside document.addEventListener('click', function(e) { if (!mobileToggle.contains(e.target) && !navMenu.contains(e.target)) { navMenu.classList.remove('active'); mobileToggle.setAttribute('aria-expanded', 'false'); mobileToggle.textContent = 'Menu'; } }); // Close mobile menu on window resize if desktop view window.addEventListener('resize', function() { if (window.innerWidth > 768) { navMenu.classList.remove('active'); mobileToggle.setAttribute('aria-expanded', 'false'); mobileToggle.textContent = 'Menu'; } }); } /** * Initialize smooth scrolling for anchor links */ function initSmoothScrolling() { const anchorLinks = document.querySelectorAll('a[href^="#"]'); anchorLinks.forEach(function(link) { link.addEventListener('click', function(e) { const targetId = this.getAttribute('href'); const targetElement = document.querySelector(targetId); if (targetElement) { e.preventDefault(); const headerHeight = document.querySelector('.site-header').offsetHeight; const targetPosition = targetElement.offsetTop - headerHeight - 20; window.scrollTo({ top: targetPosition, behavior: 'smooth' }); } }); }); } /** * Set active navigation item based on current page */ function initActiveNavigation() { const currentPage = window.location.pathname; const navLinks = document.querySelectorAll('.nav-menu a'); navLinks.forEach(function(link) { const linkPath = new URL(link.href).pathname; if (linkPath === currentPage || (currentPage === '/' && linkPath === '/index.html') || (currentPage.includes('index.html') && linkPath === '/')) { link.classList.add('active'); link.setAttribute('aria-current', 'page'); } }); } /** * Initialize accessibility features */ function initAccessibility() { // Skip to content link addSkipToContentLink(); // Keyboard navigation for mobile menu const mobileToggle = document.querySelector('.mobile-menu-toggle'); if (mobileToggle) { mobileToggle.addEventListener('keydown', function(e) { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); this.click(); } }); } // Focus management for mobile menu const navMenu = document.querySelector('.nav-menu'); if (navMenu) { navMenu.addEventListener('keydown', function(e) { if (e.key === 'Escape') { navMenu.classList.remove('active'); if (mobileToggle) { mobileToggle.setAttribute('aria-expanded', 'false'); mobileToggle.textContent = 'Menu'; mobileToggle.focus(); } } }); } } /** * Add skip to content link for accessibility */ function addSkipToContentLink() { const skipLink = document.createElement('a'); skipLink.href = '#main-content'; skipLink.textContent = 'Skip to main content'; skipLink.className = 'skip-to-content'; // Add styles for skip link skipLink.style.cssText = ` position: absolute; top: -100px; left: 20px; background: var(--color-vivid-red); color: white; padding: 10px 20px; text-decoration: none; border-radius: 4px; z-index: 10000; transition: top 0.3s ease; `; skipLink.addEventListener('focus', function() { this.style.top = '20px'; }); skipLink.addEventListener('blur', function() { this.style.top = '-100px'; }); document.body.insertBefore(skipLink, document.body.firstChild); } /** * Utility function to check if user prefers reduced motion */ function prefersReducedMotion() { return window.matchMedia('(prefers-reduced-motion: reduce)').matches; } /** * Initialize lazy loading for images (if needed in future) */ function initLazyLoading() { if ('IntersectionObserver' in window) { const imageObserver = new IntersectionObserver(function(entries, observer) { entries.forEach(function(entry) { if (entry.isIntersecting) { const img = entry.target; if (img.dataset.src) { img.src = img.dataset.src; img.classList.remove('lazy'); observer.unobserve(img); } } }); }); const lazyImages = document.querySelectorAll('img[data-src]'); lazyImages.forEach(function(img) { imageObserver.observe(img); }); } } /** * Handle external links (open in new tab with security) */ function initExternalLinks() { const externalLinks = document.querySelectorAll('a[href^="http"]:not([href*="' + window.location.hostname + '"])'); externalLinks.forEach(function(link) { link.setAttribute('target', '_blank'); link.setAttribute('rel', 'noopener noreferrer'); // Add visual indicator for external links if (!link.querySelector('.external-link-indicator')) { const indicator = document.createElement('span'); indicator.className = 'external-link-indicator'; indicator.setAttribute('aria-label', '(opens in new tab)'); indicator.innerHTML = ' ↗'; link.appendChild(indicator); } }); } // Initialize external links when DOM is ready document.addEventListener('DOMContentLoaded', initExternalLinks); })();