// 统一的组件加载函数 - 同时处理导航栏和页脚 async function loadComponents(isLanguageChange = false) { // 移除防止重复执行的机制,允许重复执行以确保最新数据被加载 try { // 1. 检查页面中是否已存在header元素(导航栏) let existingHeader = document.querySelector('header#navbar'); // 2. 如果不存在header元素,则动态加载navbar.html if (!existingHeader) { try { const navbarResponse = await fetch('/components/navbar.html'); if (navbarResponse.ok) { const navbarHTML = await navbarResponse.text(); // 将navbar HTML插入到body开头 document.body.insertAdjacentHTML('afterbegin', navbarHTML); console.log('导航栏HTML已成功加载'); } else { console.error('加载导航栏HTML失败,状态码:', navbarResponse.status); } } catch (error) { console.error('加载导航栏HTML时发生错误:', error); } } // 3. 检查页面中是否已存在footer元素 let existingFooter = document.querySelector('footer'); // 4. 如果不存在footer元素,则动态加载footer.html if (!existingFooter) { try { const footerResponse = await fetch('/components/footer.html'); if (footerResponse.ok) { const footerHTML = await footerResponse.text(); // 将footer HTML插入到body末尾 document.body.insertAdjacentHTML('beforeend', footerHTML); // 给页脚添加初始隐藏类 const footerElement = document.querySelector('footer'); if (footerElement) { footerElement.classList.add('content-hidden'); } console.log('页脚HTML已成功加载'); } else { console.error('加载页脚HTML失败,状态码:', footerResponse.status); } } catch (error) { console.error('加载页脚HTML时发生错误:', error); } } // 3. 从服务器获取最新的配置数据 let homePageData = {}; // 当语言切换时,尝试从localStorage获取数据,如果没有则从服务器获取 if (!isLanguageChange) { try { // 获取当前语言,确保传递正确的语言参数 const currentLang = window.languageManager ? window.languageManager.currentLang : 'zh'; console.log('当前语言:', currentLang); // 添加缓存控制头,确保每次都从服务器获取最新的数据 const response = await fetch(`/api/config?lang=${currentLang}`, { headers: { 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' } }); console.log('服务器响应状态:', response.status); if (response.ok) { const data = await response.json(); console.log('服务器返回数据:', data); if (data.success && data.config) { homePageData = data.config; // 将服务器数据保存到localStorage,以便下次使用 localStorage.setItem('homePageData', JSON.stringify(homePageData)); // 保存当前语言到localStorage,以便下次检查 localStorage.setItem('homePageDataLang', currentLang); console.log('从服务器更新了homePageData:', homePageData); } } } catch (error) { console.error('从服务器获取页脚数据失败,使用localStorage备用数据:', error); // 如果从服务器获取数据失败,使用localStorage数据 homePageData = JSON.parse(localStorage.getItem('homePageData') || '{}'); // 检查localStorage中的数据语言是否与当前语言一致 const currentLang = window.languageManager ? window.languageManager.currentLang : 'zh'; const cachedLang = localStorage.getItem('homePageDataLang'); if (cachedLang && cachedLang !== currentLang) { console.log('localStorage中的数据语言与当前语言不一致,尝试从服务器获取'); // 尝试从服务器获取当前语言的数据 try { const response = await fetch(`/api/config?lang=${currentLang}`, { headers: { 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' } }); if (response.ok) { const data = await response.json(); if (data.success && data.config) { homePageData = data.config; localStorage.setItem('homePageData', JSON.stringify(homePageData)); localStorage.setItem('homePageDataLang', currentLang); } } } catch (innerError) { console.error('再次尝试获取数据失败:', innerError); // 如果再次失败,使用空对象 homePageData = {}; } } console.log('使用localStorage中的homePageData:', homePageData); } } else { console.log('语言切换,从localStorage获取数据'); // 从localStorage获取数据 homePageData = JSON.parse(localStorage.getItem('homePageData') || '{}'); // 检查localStorage中的数据语言是否与当前语言一致 const currentLang = window.languageManager ? window.languageManager.currentLang : 'zh'; const cachedLang = localStorage.getItem('homePageDataLang'); if (cachedLang && cachedLang !== currentLang) { console.log('localStorage中的数据语言与当前语言不一致,尝试从服务器获取'); // 尝试从服务器获取当前语言的数据 try { const response = await fetch(`/api/config?lang=${currentLang}`, { headers: { 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' } }); if (response.ok) { const data = await response.json(); if (data.success && data.config) { homePageData = data.config; localStorage.setItem('homePageData', JSON.stringify(homePageData)); localStorage.setItem('homePageDataLang', currentLang); } } } catch (error) { console.error('获取当前语言数据失败:', error); // 如果失败,使用空对象 homePageData = {}; } } console.log('语言切换后使用的homePageData:', homePageData); } // 确保footer数据存在 const footerData = homePageData.footer || {}; // 第一格:品牌信息 const logoImage = document.getElementById('logo-image'); const logoText = document.getElementById('logo-text'); const footerLogoImage = document.getElementById('footer-logo-image'); const footerLogoText = document.getElementById('footer-logo-text'); const footerDesc = document.querySelector('[data-lang-key="footer_desc"]'); // 获取siteSettings中的LOGO设置,优先级最高 const siteSettings = JSON.parse(localStorage.getItem('siteSettings') || '{}'); // 更新品牌LOGO(导航栏和页脚) const logoSrc = siteSettings.logo || homePageData.logo || (footerData.column1 && footerData.column1.logo); if (logoSrc) { // 更新导航栏LOGO if (logoImage) { logoImage.src = logoSrc; logoImage.style.display = 'block'; logoText.style.display = 'none'; } // 更新页脚LOGO if (footerLogoImage) { footerLogoImage.src = logoSrc; footerLogoImage.style.display = 'block'; footerLogoText.style.display = 'none'; } } else { // 否则显示文字LOGO if (logoImage) { logoImage.src = ''; logoImage.style.display = 'none'; logoText.style.display = 'block'; } if (footerLogoImage) { footerLogoImage.src = ''; footerLogoImage.style.display = 'none'; footerLogoText.style.display = 'block'; } // 更新文字LOGO内容 const logoTextContent = siteSettings.logoText || homePageData.logoText || (footerData.column1 && footerData.column1.logoText) || '无穷智能自动售货机'; // 检查是否包含高亮部分 if (logoText && logoTextContent.includes('智能自动售货机')) { logoText.innerHTML = logoTextContent.replace('智能自动售货机', '智能自动售货机'); } else if (logoText) { logoText.textContent = logoTextContent; } if (footerLogoText && logoTextContent.includes('智能自动售货机')) { footerLogoText.innerHTML = logoTextContent.replace('智能自动售货机', '智能自动售货机'); } else if (footerLogoText) { footerLogoText.textContent = logoTextContent; } } // 更新页脚第一格描述信息 if (footerDesc) { // 优先使用footerData.column1.desc if (footerData.column1 && footerData.column1.desc) { footerDesc.textContent = footerData.column1.desc; } // 其次使用footerData.desc else if (footerData.desc) { footerDesc.textContent = footerData.desc; } // 保留data-lang-key属性,让语言管理器处理翻译 } // 调试信息 console.log('Footer data loaded:', { footerData: footerData, column1Desc: footerData.column1 ? footerData.column1.desc : 'N/A', footerDesc: footerData.desc, footerDescElement: footerDesc }); // 第二格:快速链接 const quickLinksTitle = document.querySelector('footer [data-lang-key="quick_links"]'); const quickLinksItems = document.querySelectorAll('footer [data-lang-key^="nav_"]'); if (footerData.column2) { if (footerData.column2.title && quickLinksTitle) { quickLinksTitle.textContent = footerData.column2.title; } if (footerData.column2.links && quickLinksItems) { // 更新快速链接项 footerData.column2.links.forEach((link, index) => { if (quickLinksItems[index]) { quickLinksItems[index].textContent = link.text; quickLinksItems[index].href = link.url || '#'; } }); } } // 第三格:联系信息 const contactInfoTitle = document.querySelector('footer [data-lang-key="contact_info"]'); const contactAddress = document.querySelector('footer [data-lang-key="contact_address"]'); const contactPhone = document.querySelector('footer [data-lang-key="contact_phone"]'); const contactEmail = document.querySelector('footer [data-lang-key="contact_email"]'); const qrCodeText = document.querySelector('footer .text-neutral-400.text-sm'); // 给二维码文本添加data-lang-key属性 if (qrCodeText && !qrCodeText.hasAttribute('data-lang-key')) { qrCodeText.setAttribute('data-lang-key', 'contact_qrcode_text'); } const qrCodeElement = document.querySelector('footer .bg-white.p-4.rounded-md.mb-3 .w-32.h-32'); if (footerData.column3) { if (footerData.column3.title && contactInfoTitle) { contactInfoTitle.textContent = footerData.column3.title; } if (footerData.column3.address && contactAddress) { contactAddress.textContent = footerData.column3.address; } if (footerData.column3.phone && contactPhone) { contactPhone.textContent = footerData.column3.phone; } if (footerData.column3.email && contactEmail) { contactEmail.textContent = footerData.column3.email; } if (footerData.column3.qrCodeText && qrCodeText) { qrCodeText.textContent = footerData.column3.qrCodeText; } // 更新二维码图片 if (footerData.column3.qrCode && qrCodeElement) { // 清空容器,移除所有旧内容 qrCodeElement.innerHTML = ''; // 创建新的二维码图片 const qrImg = document.createElement('img'); qrImg.src = footerData.column3.qrCode; qrImg.alt = '二维码'; qrImg.className = 'w-full h-full object-contain'; qrCodeElement.appendChild(qrImg); } } // 更新版权信息 const copyrightText = document.querySelector('[data-lang-key="copyright"] p'); if (copyrightText) { if (footerData.copyright) { copyrightText.innerHTML = footerData.copyright; } else if (homePageData.footer && homePageData.footer.copyright) { copyrightText.innerHTML = homePageData.footer.copyright; } } // 更新备案号信息 - 简化版 const beianInfo = document.getElementById('beian-info'); if (beianInfo) { // 只在有新数据时更新备案号,否则保持默认值 const currentLang = window.languageManager ? window.languageManager.currentLang : 'zh'; fetch(`/api/config?lang=${currentLang}`, { headers: { 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' } }) .then(response => response.json()) .then(data => { if (data.success && data.config && data.config.beian) { // 只有当服务器返回了beian数据时才更新 beianInfo.innerHTML = data.config.beian; } // 确保元素可见 beianInfo.style.display = 'block'; beianInfo.style.visibility = 'visible'; beianInfo.style.opacity = '1'; }) .catch(error => { console.error('更新备案号失败:', error); // 出错时保持默认值不变 }); } // 更新官方商城链接 const mallLinks = document.querySelectorAll('[data-lang-key="official_mall"]'); // 使用配置的链接,如果没有则使用默认值 // 检查officialMallUrl是否在images对象中(旧格式)或根对象中(新格式) const mallUrl = homePageData.officialMallUrl || (homePageData.images && homePageData.images.officialMallUrl ? homePageData.images.officialMallUrl.url : '#'); // 更新所有官方商城链接 mallLinks.forEach(link => { link.href = mallUrl; }); // 初始化移动端菜单 window.initMobileMenu = function() { // 确保元素存在 if (!document.getElementById('mobile-menu-btn') || !document.getElementById('mobile-menu')) { console.error('移动端菜单元素未找到'); return; } // 为移动端菜单按钮添加点击事件(直接绑定,不替换元素) // 移除旧的事件监听器,避免重复绑定 document.getElementById('mobile-menu-btn').onclick = function() { const mobileMenu = document.getElementById('mobile-menu'); if (mobileMenu.classList.contains('hidden')) { mobileMenu.classList.remove('hidden'); mobileMenu.style.opacity = '1'; mobileMenu.style.transform = 'translateY(0)'; } else { // 直接隐藏菜单,不使用外部函数 mobileMenu.style.opacity = '0'; mobileMenu.style.transform = 'translateY(-10px)'; setTimeout(() => { mobileMenu.classList.add('hidden'); }, 300); } }; // 为移动端菜单链接添加点击事件,点击后隐藏菜单 const mobileMenuLinks = document.querySelectorAll('#mobile-menu a'); mobileMenuLinks.forEach(link => { // 保存原始的onclick事件处理函数 const originalOnClick = link.onclick || function() {}; // 使用addEventListener添加事件监听,而不是直接覆盖onclick link.onclick = function(event) { // 执行原始的点击事件处理函数 originalOnClick.call(this, event); // 隐藏菜单 const mobileMenu = document.getElementById('mobile-menu'); if (!mobileMenu.classList.contains('hidden')) { mobileMenu.style.opacity = '0'; mobileMenu.style.transform = 'translateY(-10px)'; setTimeout(() => { mobileMenu.classList.add('hidden'); }, 300); } }; }); // 初始化移动端产品中心下拉菜单 const mobileProductsBtn = document.getElementById('mobile-products-btn'); const mobileProductsDropdown = document.getElementById('mobile-products-dropdown'); const mobileProductsArrow = document.querySelector('#mobile-products-btn i'); if (mobileProductsBtn && mobileProductsDropdown) { // 设置初始样式 mobileProductsDropdown.style.opacity = '0'; mobileProductsDropdown.style.transform = 'translateY(-10px)'; mobileProductsDropdown.style.transition = 'opacity 300ms ease, transform 300ms ease'; // 直接绑定onclick事件,会自动覆盖旧事件 mobileProductsBtn.onclick = function(event) { event.stopPropagation(); if (mobileProductsDropdown.classList.contains('hidden')) { // 显示下拉菜单 mobileProductsDropdown.classList.remove('hidden'); // 延迟设置样式以触发过渡效果 setTimeout(() => { mobileProductsDropdown.style.opacity = '1'; mobileProductsDropdown.style.transform = 'translateY(0)'; }, 10); } else { // 隐藏下拉菜单 mobileProductsDropdown.style.opacity = '0'; mobileProductsDropdown.style.transform = 'translateY(-10px)'; // 延迟添加hidden类以完成过渡效果 setTimeout(() => { mobileProductsDropdown.classList.add('hidden'); }, 300); } if (mobileProductsArrow) { mobileProductsArrow.classList.toggle('rotate-180'); } }; } // 为产品下拉菜单链接添加点击事件 const mobileProductsLinks = document.querySelectorAll('#mobile-products-dropdown a'); mobileProductsLinks.forEach(link => { // 直接绑定onclick事件,会自动覆盖旧事件 link.onclick = function() { const mobileMenu = document.getElementById('mobile-menu'); if (!mobileMenu.classList.contains('hidden')) { mobileMenu.style.opacity = '0'; mobileMenu.style.transform = 'translateY(-10px)'; setTimeout(() => { mobileMenu.classList.add('hidden'); }, 300); } }; }); } // 调用语言管理器的reinit方法,更新语言切换按钮和页面翻译 if (window.languageManager) { window.languageManager.reinit(); } // 显示页脚 const footerElement = document.querySelector('footer'); if (footerElement) { footerElement.classList.remove('content-hidden'); footerElement.classList.add('content-visible'); } // 初始化移动端菜单 window.initMobileMenu(); } catch (error) { console.error('加载页脚数据失败:', error); } } // 添加向后兼容的别名,确保现有代码仍能正常工作 window.loadFooterData = loadComponents; // 移除自动执行机制,由各个页面的初始化函数手动调用,确保执行顺序可控 // if (typeof window !== 'undefined') { // window.addEventListener('DOMContentLoaded', loadComponents); // }