/* ==================== 玄潮科技 - Main JavaScript ==================== */ (function () { 'use strict'; /* ----- DOM Ready ----- */ document.addEventListener('DOMContentLoaded', function () { initMobileMenu(); initSmoothScroll(); initHeaderScroll(); initActiveNav(); initRevealAnimations(); initCounters(); initBackToTop(); initContactForm(); initFooterYear(); }); /* ==================== Mobile Menu ==================== */ function initMobileMenu() { var btn = document.getElementById('mobile-menu-btn'); var menu = document.getElementById('mobile-menu'); if (!btn || !menu) return; btn.addEventListener('click', function () { menu.classList.toggle('hidden'); var icon = btn.querySelector('i'); if (menu.classList.contains('hidden')) { icon.className = 'fas fa-bars text-xl'; } else { icon.className = 'fas fa-xmark text-xl'; } }); // Close mobile menu when a link is clicked var links = menu.querySelectorAll('.mobile-nav-link'); links.forEach(function (link) { link.addEventListener('click', function () { menu.classList.add('hidden'); btn.querySelector('i').className = 'fas fa-bars text-xl'; }); }); } /* ==================== Smooth Scroll ==================== */ function initSmoothScroll() { var links = document.querySelectorAll('a[href^="#"]'); links.forEach(function (link) { link.addEventListener('click', function (e) { var href = link.getAttribute('href'); if (href === '#' || href === '') return; var target = document.querySelector(href); if (!target) return; e.preventDefault(); var headerHeight = document.getElementById('header').offsetHeight; var targetPos = target.getBoundingClientRect().top + window.pageYOffset - headerHeight + 1; window.scrollTo({ top: targetPos, behavior: 'smooth' }); }); }); } /* ==================== Header Scroll Effect ==================== */ function initHeaderScroll() { var header = document.getElementById('header'); if (!header) return; window.addEventListener('scroll', function () { if (window.scrollY > 10) { header.classList.add('scrolled'); } else { header.classList.remove('scrolled'); } }); } /* ==================== Active Nav Highlighting ==================== */ function initActiveNav() { var sections = document.querySelectorAll('section[id]'); var navLinks = document.querySelectorAll('.nav-link'); if (!sections.length || !navLinks.length) return; var observer = new IntersectionObserver(function (entries) { entries.forEach(function (entry) { if (entry.isIntersecting) { var id = entry.target.getAttribute('id'); navLinks.forEach(function (link) { if (link.getAttribute('href') === '#' + id) { link.classList.add('active'); link.classList.remove('text-gray-600'); } else { link.classList.remove('active'); link.classList.add('text-gray-600'); } }); } }); }, { rootMargin: '-40% 0px -55% 0px' }); sections.forEach(function (section) { observer.observe(section); }); } /* ==================== Reveal Animations ==================== */ function initRevealAnimations() { var elements = document.querySelectorAll('.reveal-up, .reveal-left, .reveal-right'); if (!elements.length) return; // Set animation delay from inline style elements.forEach(function (el) { var styleDelay = el.style.animationDelay; if (styleDelay) { el.style.setProperty('--reveal-delay', styleDelay); } }); var observer = new IntersectionObserver(function (entries) { entries.forEach(function (entry) { if (entry.isIntersecting) { entry.target.classList.add('revealed'); observer.unobserve(entry.target); } }); }, { threshold: 0.15, rootMargin: '0px 0px -50px 0px' }); elements.forEach(function (el) { observer.observe(el); }); } /* ==================== Counter Animation ==================== */ function initCounters() { var counters = document.querySelectorAll('.counter'); if (!counters.length) return; var observer = new IntersectionObserver(function (entries) { entries.forEach(function (entry) { if (entry.isIntersecting) { animateCounter(entry.target); observer.unobserve(entry.target); } }); }, { threshold: 0.5 }); counters.forEach(function (counter) { observer.observe(counter); }); } function animateCounter(el) { var target = parseInt(el.getAttribute('data-target'), 10); var duration = 2000; var startTime = null; function step(timestamp) { if (!startTime) startTime = timestamp; var progress = Math.min((timestamp - startTime) / duration, 1); // Ease out cubic var eased = 1 - Math.pow(1 - progress, 3); var current = Math.floor(eased * target); el.textContent = current; if (progress < 1) { requestAnimationFrame(step); } else { el.textContent = target; } } requestAnimationFrame(step); } /* ==================== Back to Top ==================== */ function initBackToTop() { var btn = document.getElementById('back-to-top'); if (!btn) return; window.addEventListener('scroll', function () { if (window.scrollY > 500) { btn.classList.add('visible'); btn.classList.remove('opacity-0', 'invisible'); } else { btn.classList.remove('visible'); btn.classList.add('opacity-0', 'invisible'); } }); btn.addEventListener('click', function () { window.scrollTo({ top: 0, behavior: 'smooth' }); }); } /* ==================== Contact Form ==================== */ function initContactForm() { var form = document.getElementById('contact-form'); if (!form) return; var successMsg = document.getElementById('form-success'); form.addEventListener('submit', function (e) { e.preventDefault(); // Clear previous errors var errorMessages = form.querySelectorAll('.error-msg'); errorMessages.forEach(function (msg) { msg.classList.add('hidden'); }); var inputs = form.querySelectorAll('.form-input'); inputs.forEach(function (input) { input.classList.remove('error'); }); var isValid = true; // Validate name var name = document.getElementById('name'); if (!name.value.trim()) { showError(name, 'name'); isValid = false; } // Validate phone (Chinese phone: 11 digits starting with 1, or landline) var phone = document.getElementById('phone'); var phoneVal = phone.value.trim(); if (!phoneVal || !/^[\d\s\-+()]{7,20}$/.test(phoneVal)) { showError(phone, 'phone'); isValid = false; } // Validate email var email = document.getElementById('email'); var emailVal = email.value.trim(); if (!emailVal || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(emailVal)) { showError(email, 'email'); isValid = false; } // Validate company var company = document.getElementById('company'); if (!company.value.trim()) { showError(company, 'company'); isValid = false; } // Validate message var message = document.getElementById('message'); if (!message.value.trim()) { showError(message, 'message'); isValid = false; } if (isValid) { // === Submit logic === // 此处可对接后端API,示例: // fetch('/api/contact', { method: 'POST', body: new FormData(form) }) // .then(res => res.json()) // .then(data => { ... }) // .catch(err => { ... }); // 模拟提交成功 form.style.display = 'none'; successMsg.classList.remove('hidden'); // 5秒后恢复表单 setTimeout(function () { form.reset(); form.style.display = ''; successMsg.classList.add('hidden'); }, 5000); } }); function showError(input, fieldId) { input.classList.add('error'); var errorMsg = input.parentElement.querySelector('.error-msg'); if (errorMsg) { errorMsg.classList.remove('hidden'); } } // Clear error on input var allInputs = form.querySelectorAll('.form-input'); allInputs.forEach(function (input) { input.addEventListener('input', function () { input.classList.remove('error'); var errorMsg = input.parentElement.querySelector('.error-msg'); if (errorMsg) errorMsg.classList.add('hidden'); }); }); } /* ==================== Footer Year ==================== */ function initFooterYear() { var yearEl = document.getElementById('current-year'); if (yearEl) { yearEl.textContent = new Date().getFullYear(); } } })();