// 主JavaScript文件 - 爱鉴花官方网站 document.addEventListener('DOMContentLoaded', function() { // 初始化函数 initWebsite(); }); function initWebsite() { // 初始化导航栏滚动效果 initNavbarScroll(); // 初始化滚动动画 initScrollAnimation(); // 初始化表单验证 initFormValidation(); // 初始化计数器动画 initCounterAnimation(); // 初始化图片懒加载 initLazyLoading(); // 初始化移动端菜单 initMobileMenu(); // 初始化平滑滚动 initSmoothScroll(); // 初始化悬停动画 initHoverEffects(); // 初始化加载状态 initLoadingStates(); // 初始化页面过渡效果 initPageTransitions(); } // 导航栏滚动效果 function initNavbarScroll() { const navbar = document.querySelector('.navbar'); window.addEventListener('scroll', function() { if (window.scrollY > 100) { navbar.classList.add('navbar-scrolled'); } else { navbar.classList.remove('navbar-scrolled'); } }); } // 滚动动画效果 function initScrollAnimation() { const animatedElements = document.querySelectorAll('.card, .feature-icon'); const observerOptions = { threshold: 0.1, rootMargin: '0px 0px -50px 0px' }; const observer = new IntersectionObserver(function(entries) { entries.forEach(function(entry) { if (entry.isIntersecting) { entry.target.classList.add('fade-in-up'); observer.unobserve(entry.target); } }); }, observerOptions); animatedElements.forEach(function(element) { observer.observe(element); }); } // 表单验证 function initFormValidation() { const forms = document.querySelectorAll('form'); forms.forEach(function(form) { form.addEventListener('submit', function(e) { if (!validateForm(form)) { e.preventDefault(); } }); }); } function validateForm(form) { let isValid = true; const inputs = form.querySelectorAll('input[required], textarea[required]'); inputs.forEach(function(input) { if (!input.value.trim()) { showError(input, '此字段为必填项'); isValid = false; } else if (input.type === 'email' && !isValidEmail(input.value)) { showError(input, '请输入有效的邮箱地址'); isValid = false; } else { clearError(input); } }); return isValid; } function isValidEmail(email) { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); } function showError(input, message) { clearError(input); const errorDiv = document.createElement('div'); errorDiv.className = 'invalid-feedback'; errorDiv.textContent = message; input.classList.add('is-invalid'); input.parentNode.appendChild(errorDiv); } function clearError(input) { input.classList.remove('is-invalid'); const errorDiv = input.parentNode.querySelector('.invalid-feedback'); if (errorDiv) { errorDiv.remove(); } } // 计数器动画 function initCounterAnimation() { const counters = document.querySelectorAll('.counter'); if (counters.length > 0) { const observer = new IntersectionObserver(function(entries) { entries.forEach(function(entry) { if (entry.isIntersecting) { animateCounters(); observer.unobserve(entry.target); } }); }); observer.observe(counters[0]); } } function animateCounters() { const counters = document.querySelectorAll('.counter'); counters.forEach(function(counter) { const target = parseInt(counter.getAttribute('data-target')); const duration = 2000; // 2 seconds const frameDuration = 1000 / 60; // 60fps const totalFrames = Math.round(duration / frameDuration); let currentFrame = 0; const updateCounter = function() { currentFrame++; const progress = currentFrame / totalFrames; const currentValue = Math.round(target * progress); counter.textContent = currentValue.toLocaleString(); if (currentFrame < totalFrames) { requestAnimationFrame(updateCounter); } else { counter.textContent = target.toLocaleString(); } }; updateCounter(); }); } // 图片懒加载 function initLazyLoading() { if ('IntersectionObserver' in window) { const lazyImages = document.querySelectorAll('img.lazy-load'); const imageObserver = new IntersectionObserver(function(entries) { entries.forEach(function(entry) { if (entry.isIntersecting) { const img = entry.target; // 确保图片完全加载后显示 img.onload = function() { img.classList.add('loaded'); }; // 处理data-src属性或直接使用src if (img.hasAttribute('data-src')) { img.src = img.getAttribute('data-src'); img.removeAttribute('data-src'); } imageObserver.unobserve(img); } }); }, { threshold: 0.1, rootMargin: '50px 0px' }); lazyImages.forEach(function(img) { imageObserver.observe(img); }); } else { // 浏览器不支持IntersectionObserver时的降级方案 const lazyImages = document.querySelectorAll('img.lazy-load'); lazyImages.forEach(function(img) { img.classList.add('loaded'); }); } } // 移动端菜单处理 function initMobileMenu() { const navbarToggler = document.querySelector('.navbar-toggler'); const navbarCollapse = document.querySelector('.navbar-collapse'); if (navbarToggler && navbarCollapse) { navbarToggler.addEventListener('click', function() { navbarCollapse.classList.toggle('show'); // 添加菜单动画效果 navbarToggler.classList.toggle('active'); }); // 点击菜单项后自动关闭菜单(移动端) const navLinks = document.querySelectorAll('.navbar-nav .nav-link'); navLinks.forEach(function(link) { link.addEventListener('click', function() { if (window.innerWidth < 992) { navbarCollapse.classList.remove('show'); navbarToggler.classList.remove('active'); } }); }); } } // 平滑滚动效果 function initSmoothScroll() { // 内部链接平滑滚动 const internalLinks = document.querySelectorAll('a[href^="#"]'); internalLinks.forEach(function(link) { link.addEventListener('click', function(e) { e.preventDefault(); const targetId = this.getAttribute('href').substring(1); const targetElement = document.getElementById(targetId); if (targetElement) { const offsetTop = targetElement.offsetTop - 80; // 考虑导航栏高度 window.scrollTo({ top: offsetTop, behavior: 'smooth' }); } }); }); // 返回顶部按钮 const backToTopBtn = document.createElement('button'); backToTopBtn.className = 'back-to-top'; backToTopBtn.innerHTML = '↑'; backToTopBtn.setAttribute('aria-label', '返回顶部'); backToTopBtn.addEventListener('click', function() { window.scrollTo({ top: 0, behavior: 'smooth' }); }); // 滚动时显示/隐藏返回顶部按钮 window.addEventListener('scroll', debounce(function() { if (window.scrollY > 500) { backToTopBtn.classList.add('show'); } else { backToTopBtn.classList.remove('show'); } }, 100)); document.body.appendChild(backToTopBtn); } // 悬停动画效果 function initHoverEffects() { // 卡片悬停效果 const cards = document.querySelectorAll('.card, .product-card, .news-card'); cards.forEach(function(card) { card.addEventListener('mouseenter', function() { this.style.transform = 'translateY(-5px) scale(1.02)'; this.style.boxShadow = '0 10px 25px rgba(0, 0, 0, 0.15)'; }); card.addEventListener('mouseleave', function() { this.style.transform = 'translateY(0) scale(1)'; this.style.boxShadow = '0 4px 6px rgba(0, 0, 0, 0.1)'; }); }); // 按钮悬停效果 const buttons = document.querySelectorAll('.btn, .nav-link'); buttons.forEach(function(button) { button.addEventListener('mouseenter', function() { this.style.transform = 'translateY(-2px)'; }); button.addEventListener('mouseleave', function() { this.style.transform = 'translateY(0)'; }); }); } // 加载状态指示器 function initLoadingStates() { const forms = document.querySelectorAll('form'); forms.forEach(function(form) { form.addEventListener('submit', function() { const submitBtn = this.querySelector('button[type="submit"]'); if (submitBtn) { submitBtn.disabled = true; submitBtn.innerHTML = ' 处理中...'; // 3秒后恢复按钮状态(防止无限加载) setTimeout(function() { submitBtn.disabled = false; submitBtn.innerHTML = submitBtn.getAttribute('data-original-text') || '提交'; }, 3000); } }); }); // 保存按钮原始文本 document.addEventListener('DOMContentLoaded', function() { const submitButtons = document.querySelectorAll('button[type="submit"]'); submitButtons.forEach(function(btn) { btn.setAttribute('data-original-text', btn.textContent); }); }); } // 页面过渡效果 function initPageTransitions() { // 链接点击时的过渡效果 const links = document.querySelectorAll('a:not([href^="#"]):not([href^="javascript"])'); links.forEach(function(link) { link.addEventListener('click', function(e) { if (this.href && !this.target && !this.hasAttribute('download')) { e.preventDefault(); // 添加页面离开动画 document.body.classList.add('page-leaving'); setTimeout(function() { window.location.href = link.href; }, 300); } }); }); // 页面进入动画 document.body.classList.add('page-entering'); setTimeout(function() { document.body.classList.remove('page-entering'); }, 300); } // 工具函数:防抖 function debounce(func, wait) { let timeout; return function() { const context = this; const args = arguments; clearTimeout(timeout); timeout = setTimeout(function() { func.apply(context, args); }, wait); }; } // 工具函数:节流 function throttle(func, limit) { let inThrottle; return function() { const args = arguments; const context = this; if (!inThrottle) { func.apply(context, args); inThrottle = true; setTimeout(function() { inThrottle = false; }, limit); } }; } // 页面性能监控 function monitorPerformance() { // 页面加载时间 window.addEventListener('load', function() { const loadTime = performance.timing.loadEventEnd - performance.timing.navigationStart; console.log('页面加载时间:', loadTime + 'ms'); }); // 最大内容绘制(LCP) new PerformanceObserver(function(entryList) { const entries = entryList.getEntries(); const lastEntry = entries[entries.length - 1]; console.log('LCP:', lastEntry.startTime); }).observe({type: 'largest-contentful-paint', buffered: true}); } // 错误监控 function monitorErrors() { window.addEventListener('error', function(e) { console.error('JavaScript错误:', e.error); }); window.addEventListener('unhandledrejection', function(e) { console.error('未处理的Promise拒绝:', e.reason); }); } // 初始化性能和错误监控 monitorPerformance(); monitorErrors(); // 通用JavaScript功能 // 导航栏滚动效果 window.addEventListener('scroll', function() { const navbar = document.querySelector('.navbar'); if (window.scrollY > 50) { navbar.classList.add('scrolled'); } else { navbar.classList.remove('scrolled'); } }); // 懒加载图片 document.addEventListener('DOMContentLoaded', function() { const lazyImages = [].slice.call(document.querySelectorAll('img.lazy-load')); if ('IntersectionObserver' in window) { let lazyImageObserver = new IntersectionObserver(function(entries, observer) { entries.forEach(function(entry) { if (entry.isIntersecting) { let lazyImage = entry.target; lazyImage.src = lazyImage.dataset.src || lazyImage.src; lazyImage.classList.remove('lazy-load'); lazyImageObserver.unobserve(lazyImage); } }); }); lazyImages.forEach(function(lazyImage) { lazyImageObserver.observe(lazyImage); }); } }); // 平滑滚动 document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); const target = document.querySelector(this.getAttribute('href')); if (target) { window.scrollTo({ top: target.offsetTop - 76, behavior: 'smooth' }); } }); }); // 表单验证增强 (function() { 'use strict'; window.addEventListener('load', function() { // 获取所有表单并阻止默认提交行为 var forms = document.getElementsByClassName('needs-validation'); var validation = Array.prototype.filter.call(forms, function(form) { form.addEventListener('submit', function(event) { if (form.checkValidity() === false) { event.preventDefault(); event.stopPropagation(); } form.classList.add('was-validated'); }, false); }); }, false); })(); // 动态年份更新 document.addEventListener('DOMContentLoaded', function() { const yearElements = document.querySelectorAll('.current-year'); const currentYear = new Date().getFullYear(); yearElements.forEach(element => { element.textContent = currentYear; }); });