// 地表水环境质量监测方案 - 主要JavaScript逻辑 // 页面初始化 document.addEventListener('DOMContentLoaded', function() { console.log('🌊 环保订单班水质监测页面加载完成'); // 初始化Lucide图标 if (typeof lucide !== 'undefined') { lucide.createIcons(); } // 初始化组件 initNavigation(); initAnimations(); initLazyLoading(); initSmoothScroll(); updateStats(); initThemeToggle(); }); // 导航功能 function initNavigation() { const navItems = document.querySelectorAll('.nav-item'); const sections = document.querySelectorAll('.section'); // 点击导航项滚动到对应区块 navItems.forEach((item, index) => { item.addEventListener('click', () => { // 移除所有活跃状态 navItems.forEach(nav => nav.classList.remove('active')); // 添加当前活跃状态 item.classList.add('active'); // 滚动到对应区块 if (sections[index]) { const targetSection = sections[index]; const offsetTop = targetSection.offsetTop - 100; window.scrollTo({ top: offsetTop, behavior: 'smooth' }); } }); }); // 滚动时更新导航活跃状态 window.addEventListener('scroll', () => { let current = ''; sections.forEach((section, index) => { const sectionTop = section.offsetTop - 150; if (scrollY >= sectionTop) { current = index; } }); navItems.forEach((item, index) => { item.classList.remove('active'); if (index === current) { item.classList.add('active'); } }); }); } // 动画初始化 function initAnimations() { // 使用 Intersection Observer 实现滚动动画 const observerOptions = { root: null, rootMargin: '0px', threshold: 0.1 }; const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('fade-in'); observer.unobserve(entry.target); } }); }, observerOptions); // 观察所有需要动画的元素 const animatedElements = document.querySelectorAll('.card, .expert-intro'); animatedElements.forEach(el => { el.style.opacity = '0'; observer.observe(el); }); } // 图片懒加载 function initLazyLoading() { const images = document.querySelectorAll('img[data-src]'); const imageObserver = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) { const img = entry.target; const src = img.getAttribute('data-src'); // 创建新图片对象来预加载 const tempImg = new Image(); tempImg.onload = function() { img.src = src; img.classList.add('loaded'); }; tempImg.onerror = function() { // 如果图片加载失败,使用占位图 img.src = 'data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" width="400" height="300" viewBox="0 0 400 300"%3E%3Crect width="400" height="300" fill="%23e0f2fe"/%3E%3Ctext x="50%25" y="50%25" dominant-baseline="middle" text-anchor="middle" font-family="system-ui" font-size="20" fill="%230284c7"%3E图片加载中%3C/text%3E%3C/svg%3E'; img.classList.add('error'); }; tempImg.src = src; img.removeAttribute('data-src'); observer.unobserve(img); } }); }); images.forEach(img => { imageObserver.observe(img); }); } // 平滑滚动 function initSmoothScroll() { // 为所有锚点链接添加平滑滚动 document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); const targetId = this.getAttribute('href'); if (targetId === '#') return; const target = document.querySelector(targetId); if (target) { target.scrollIntoView({ behavior: 'smooth', block: 'start' }); } }); }); } // 更新统计数据 - 环保监测数据 function updateStats() { // 动画数字增长效果 - 环保水质监测相关数据 const stats = [ { selector: '.monitoring-points', value: 144, suffix: '个' }, { selector: '.quality-indicators', value: 26, suffix: '项' }, { selector: '.sampling-frequency', value: 12, suffix: '次/年' }, { selector: '.data-accuracy', value: 95, suffix: '%' }, { selector: '.quality-control', value: 10, suffix: '%' }, { selector: '.project-budget', value: 45, suffix: '万元' }, { selector: '.team-members', value: 10, suffix: '人' }, { selector: '.monitoring-cycle', value: 12, suffix: '个月' } ]; stats.forEach(stat => { const element = document.querySelector(stat.selector); if (element) { animateValue(element, 0, stat.value, 2000, stat.suffix); } }); } // 数字动画函数 function animateValue(element, start, end, duration, suffix = '') { const startTime = performance.now(); function update(currentTime) { const elapsed = currentTime - startTime; const progress = Math.min(elapsed / duration, 1); // 使用缓动函数 const easeOutQuad = progress * (2 - progress); const current = Math.floor(start + (end - start) * easeOutQuad); element.textContent = current + suffix; if (progress < 1) { requestAnimationFrame(update); } } requestAnimationFrame(update); } // 错误处理 window.addEventListener('error', function(e) { if (e.target.tagName === 'IMG') { console.warn('图片加载失败:', e.target.src); e.target.src = 'data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" width="400" height="300" viewBox="0 0 400 300"%3E%3Crect width="400" height="300" fill="%23e0f2fe"/%3E%3Ctext x="50%25" y="50%25" dominant-baseline="middle" text-anchor="middle" font-family="system-ui" font-size="20" fill="%230284c7"%3E图片暂时无法显示%3C/text%3E%3C/svg%3E'; e.target.classList.add('error'); } }, true); // 移动端优化 if ('ontouchstart' in window) { document.body.classList.add('touch-device'); // 移动端点击优化 let touchStartTime; document.addEventListener('touchstart', () => { touchStartTime = Date.now(); }); document.addEventListener('touchend', (e) => { const touchEndTime = Date.now(); if (touchEndTime - touchStartTime < 200) { // 快速点击 e.preventDefault(); } }); } // 性能监控 if (window.performance && window.performance.timing) { window.addEventListener('load', () => { setTimeout(() => { const timing = window.performance.timing; const loadTime = timing.loadEventEnd - timing.navigationStart; console.log(`页面加载时间: ${loadTime}ms`); // 如果加载时间过长,提示用户 if (loadTime > 3000) { console.warn('页面加载时间较长,可能需要优化'); } }, 0); }); } // 主题切换功能 function initThemeToggle() { const themeToggleBtn = document.getElementById('themeToggleBtn'); // 从localStorage读取用户的主题偏好 const savedTheme = localStorage.getItem('theme'); // 如果没有保存的偏好,默认使用暗色主题 if (savedTheme === 'dark' || savedTheme === null) { document.body.classList.add('dark-theme'); } // 点击切换主题 if (themeToggleBtn) { themeToggleBtn.addEventListener('click', () => { document.body.classList.toggle('dark-theme'); // 保存用户偏好 if (document.body.classList.contains('dark-theme')) { localStorage.setItem('theme', 'dark'); } else { localStorage.setItem('theme', 'light'); } // 重新初始化图标以确保正确显示 if (typeof lucide !== 'undefined') { lucide.createIcons(); } }); } }