@@ -13,6 +13,7 @@
{if condition="!empty($header_categorys)"}
< div class = "header-nav-item" >
< div class = "header-nav-title" > {:lang_i18n('产品列表')}< / div >
<!-- style=" opacity: 1;" -->
< div class = "header-dropdown" >
< div class = "header-dropdown-tabs" >
{volist name="header_categorys" id="vo" key="idx"}
@@ -190,9 +191,9 @@
< / div >
< div style = "width: 100vw;height: 64px;" > < / div >
< div id = "mhk" > < / div >
< script >
// // 获取所有包含商品卡片的元素
< script >
// 获取所有包含商品卡片的元素
const productCards = document . querySelectorAll ( '.header-buy-product-card' ) ;
productCards . forEach ( card => {
@@ -223,6 +224,7 @@
hoverImg . style . opacity = '0' ;
} ) ;
} ) ;
// 产品列表在hover复位tabs选择
const productNavContainer = document . querySelector ( '.header-nav-item:first-child' ) ;
@@ -247,20 +249,15 @@
} ) ;
}
const tabItems1 = document . querySelectorAll ( '.header-tab-item' ) ;
const tabContents = document . querySelectorAll ( '.header-tab-content' ) ;
tabItems1 . forEach ( tab =>
{
tab . addEventListener ( 'mouseenter' , ( ) =>
{
tabItems1 . forEach ( tab => {
tab . addEventListener ( 'mouseenter' , ( ) => {
tabItems1 . forEach ( item => item . classList . remove ( 'active' ) ) ;
tab . classList . add ( 'active' ) ;
const tabId = tab . getAttribute ( 'data-tab' ) ;
tabContents . forEach ( content =>
{
tabContents . forEach ( content => {
content . classList . remove ( 'active' ) ;
if ( content . id === tabId ) {
content . classList . add ( 'active' ) ;
@@ -271,33 +268,31 @@
let searchHistory = JSON . parse ( localStorage . getItem ( 'searchHistory' ) || '[]' ) ;
function renderHistory ( )
{
function renderHistory ( ) {
const historyList = document . getElementById ( 'historyList' ) ;
const historySection = document . getElementById ( 'searchHistory' ) ;
if ( searchHistory . length === 0 ) {
historySection . style . display = 'none' ;
if ( historySection ) historySection . style . display = 'none' ;
return ;
}
historySection . style . display = 'block' ;
if ( historySection ) historySection . style . display = 'block' ;
if ( historyList ) {
historyList . innerHTML = searchHistory . map ( ( item , index ) => `
<div class="header-history-item" data-keyword=" ${ item } ">
<span> ${ item } </span>
<span class="header-delete-icon" data-index=" ${ index } ">✕</span>
</div>
` ) . join ( '' ) ;
document . querySelectorAll ( '.header-history-item' ) . forEach ( item =>
{
}
document . querySelectorAll ( '.header-history-item' ) . forEach ( item => {
const keyword = item . getAttribute ( 'data-keyword' ) ;
const deleteBtn = item . querySelector ( '.header-delete-icon' ) ;
item . addEventListener ( 'click' , ( e ) =>
{
item . addEventListener ( 'click' , ( e ) => {
if ( e . target === deleteBtn ) return ;
performSearch ( keyword ) ;
} ) ;
if ( deleteBtn ) {
deleteBtn . addEventListener ( 'click' , ( e ) =>
{
deleteBtn . addEventListener ( 'click' , ( e ) => {
e . stopPropagation ( ) ;
const index = parseInt ( deleteBtn . getAttribute ( 'data-index' ) ) ;
searchHistory . splice ( index , 1 ) ;
@@ -308,8 +303,7 @@
} ) ;
}
function addToHistory ( keyword )
{
function addToHistory ( keyword ) {
if ( ! keyword . trim ( ) ) return ;
searchHistory = searchHistory . filter ( item => item !== keyword ) ;
searchHistory . unshift ( keyword ) ;
@@ -320,16 +314,14 @@
const clearHistoryBtn = document . getElementById ( 'clearHistory' ) ;
if ( clearHistoryBtn ) {
clearHistoryBtn . addEventListener ( 'click' , ( ) =>
{
clearHistoryBtn . addEventListener ( 'click' , ( ) => {
searchHistory = [ ] ;
localStorage . setItem ( 'searchHistory' , JSON . stringify ( searchHistory ) ) ;
renderHistory ( ) ;
} ) ;
}
function performSearch ( keyword )
{
function performSearch ( keyword ) {
if ( keyword . trim ( ) ) {
addToHistory ( keyword ) ;
window . location . href = "{:url('product/search')}?keywords=" + encodeURIComponent ( keyword ) ;
@@ -344,67 +336,178 @@
const searchSubmit = document . querySelector ( '.header-search-submit' ) ;
const langDropdown = document . getElementById ( 'langDropdown' ) ;
const buyDropdown = document . getElementById ( 'buyDropdown' ) ;
const mhk = document . getElementById ( 'mhk' ) ;
const body = document . body ;
const langCloseBtn = document . querySelector ( '.header-lang-dropdown-delete-icon' ) ;
const searchCloseBtn = document . querySelector ( '.header-search-dropdown-delete-icon' ) ;
// 语言关闭按钮
if ( langCloseBtn && langCloseBtn ) {
langCloseBtn . addEventListener ( 'click' , ( e ) =>
{
e . stopPropagation ( ) ;
langDropdown . classList . remove ( 'show' ) ;
// 保存滚动位置
let scrollTopPosition = 0 ;
} ) ;
// 打开蒙版层(禁止滚动,不抖动)
function openOverlay ( ) {
if ( mhk && mhk . style . display !== 'block' ) {
// 保存当前滚动位置
scrollTopPosition = window . pageYOffset || document . documentElement . scrollTop ;
mhk . style . display = 'block' ;
// 禁止滚动,保持位置
body . style . position = 'fixed' ;
body . style . top = ` - ${ scrollTopPosition } px ` ;
body . style . left = '0' ;
body . style . right = '0' ;
body . style . width = '100%' ;
}
//搜索关闭
if ( searchCloseBtn && searchCloseBtn ) {
searchCloseBtn . addEventListener ( 'click' , ( e ) =>
{
e . stopPropagation ( ) ;
searchDropdown . classList . remove ( 'show' ) ;
} ) ;
}
// 鼠标移入导航项时,关闭购买下拉框
// 关闭蒙版层(恢复滚动)
function closeOverlay ( ) {
if ( mhk && mhk . style . display === 'block' ) {
const isBuyOpen = buyDropdown && buyDropdown . classList . contains ( 'show' ) ;
const isSearchOpen = searchDropdown && searchDropdown . classList . contains ( 'show' ) ;
const isLangOpen = langDropdown && langDropdown . classList . contains ( 'show' ) ;
// 检查是否有任何导航下拉菜单打开
let hasNavOpen = false ;
document . querySelectorAll ( '.header-dropdown' ) . forEach ( dropdown => {
const style = window . getComputedStyle ( dropdown ) ;
if ( style . opacity === '1' ) {
hasNavOpen = true ;
}
} ) ;
if ( ! isBuyOpen && ! isSearchOpen && ! isLangOpen && ! hasNavOpen ) {
mhk . style . display = 'none' ;
// 恢复滚动
body . style . position = '' ;
body . style . top = '' ;
body . style . left = '' ;
body . style . right = '' ;
body . style . width = '' ;
// 恢复滚动位置
window . scrollTo ( 0 , scrollTopPosition ) ;
}
}
}
// ========== header-dropdown 导航下拉菜单打开时显示蒙版 ==========
function initNavDropdownOverlay ( ) {
const navItems = document . querySelectorAll ( '.header-nav-item' ) ;
navItems . forEach ( item =>
{
let hideTimer = null ;
i tem. addEventListener ( 'mouseenter' , ( ) =>
{
navI tems . forEach ( item => {
const dropdown = item . querySelector ( '.header-dropdown' ) ;
if ( ! dropdown ) return ;
buyDropdown . classList . remove ( 'show' ) ;
langDropdown . classList . remove ( 'show' ) ;
searchDropdown . classLis t. remove ( 'show' ) ;
// 鼠标移入导航项
item . addEventListener ( 'mouseenter' , ( ) => {
if ( hideTimer ) clearTimeou t ( hideTimer ) ;
openOverlay ( ) ;
} ) ;
// 鼠标移出导航项
item . addEventListener ( 'mouseleave' , ( ) => {
hideTimer = setTimeout ( ( ) => {
const isHoveringDropdown = dropdown && dropdown . matches ( ':hover' ) ;
if ( ! isHoveringDropdown ) {
const isBuyOpen = buyDropdown && buyDropdown . classList . contains ( 'show' ) ;
const isSearchOpen = searchDropdown && searchDropdown . classList . contains ( 'show' ) ;
const isLangOpen = langDropdown && langDropdown . classList . contains ( 'show' ) ;
if ( ! isBuyOpen && ! isSearchOpen && ! isLangOpen ) {
closeOverlay ( ) ;
}
}
} , 100 ) ;
} ) ;
// 鼠标移入下拉菜单
dropdown . addEventListener ( 'mouseenter' , ( ) => {
if ( hideTimer ) clearTimeout ( hideTimer ) ;
openOverlay ( ) ;
} ) ;
// 鼠标移出下拉菜单
dropdown . addEventListener ( 'mouseleave' , ( ) => {
hideTimer = setTimeout ( ( ) => {
const isHoveringNav = item && item . matches ( ':hover' ) ;
if ( ! isHoveringNav ) {
const isBuyOpen = buyDropdown && buyDropdown . classList . contains ( 'show' ) ;
const isSearchOpen = searchDropdown && searchDropdown . classList . contains ( 'show' ) ;
const isLangOpen = langDropdown && langDropdown . classList . contains ( 'show' ) ;
if ( ! isBuyOpen && ! isSearchOpen && ! isLangOpen ) {
closeOverlay ( ) ;
}
}
} , 100 ) ;
} ) ;
} ) ;
}
// 关闭所有导航下拉菜单
function closeAllNavDropdowns ( ) {
document . querySelectorAll ( '.header-dropdown' ) . forEach ( dropdown => {
dropdown . style . opacity = '' ;
dropdown . style . transform = '' ;
dropdown . style . pointerEvents = '' ;
} ) ;
}
// 语言关闭按钮
if ( langCloseBtn ) {
langCloseBtn . addEventListener ( 'click' , ( e ) => {
e . stopPropagation ( ) ;
if ( langDropdown ) langDropdown . classList . remove ( 'show' ) ;
closeOverlay ( ) ;
} ) ;
}
// 搜索关闭按钮
if ( searchCloseBtn ) {
searchCloseBtn . addEventListener ( 'click' , ( e ) => {
e . stopPropagation ( ) ;
if ( searchDropdown ) searchDropdown . classList . remove ( 'show' ) ;
closeOverlay ( ) ;
} ) ;
}
// 鼠标移入导航项时,关闭其他弹窗
const navItems = document . querySelectorAll ( '.header-nav-item' ) ;
navItems . forEach ( item => {
item . addEventListener ( 'mouseenter' , ( ) => {
if ( buyDropdown ) buyDropdown . classList . remove ( 'show' ) ;
if ( langDropdown ) langDropdown . classList . remove ( 'show' ) ;
if ( searchDropdown ) searchDropdown . classList . remove ( 'show' ) ;
} ) ;
} ) ;
// 搜索按钮点击
if ( searchBtn && searchDropdown ) {
searchBtn . addEventListener ( 'click' , ( e ) =>
{
searchBtn . addEventListener ( 'click' , ( e ) => {
e . stopPropagation ( ) ;
if ( langDropdown ) langDropdown . classList . remove ( 'show' ) ;
if ( buyDropdown ) buyDropdown . classList . remove ( 'show' ) ;
searchDropdown . classList . toggle ( 'show' ) ;
if ( searchDropdown . classList . contains ( 'show' ) ) {
renderHistory ( ) ;
openOverlay ( ) ;
} else {
closeOverlay ( ) ;
}
} ) ;
}
if ( searchSubmit ) {
searchSubmit . addEventListener ( 'click' , ( ) =>
{
searchSubmit . addEventListener ( 'click' , ( ) => {
performSearch ( searchInput . value ) ;
} ) ;
}
if ( searchInput ) {
searchInput . addEventListener ( 'keypress' , ( e ) =>
{
searchInput . addEventListener ( 'keypress' , ( e ) => {
if ( e . key === 'Enter' ) {
performSearch ( searchInput . value ) ;
}
@@ -412,37 +515,44 @@
}
const hotProducts = document . querySelectorAll ( '.header-hot-product-item' ) ;
hotProducts . forEach ( product =>
{
product . addEventListener ( 'click' , ( ) =>
{
hotProducts . forEach ( product => {
product . addEventListener ( 'click' , ( ) => {
const keyword = product . getAttribute ( 'data-keyword' ) ;
if ( keyword ) performSearch ( keyword ) ;
} ) ;
} ) ;
// 语言按钮点击
const langBtn = document . querySelector ( '.header-lang-wrapper .header-nav-btn' ) ;
if ( langBtn && langDropdown ) {
langBtn . addEventListener ( 'click' , ( e ) =>
{
langBtn . addEventListener ( 'click' , ( e ) => {
e . stopPropagation ( ) ;
if ( searchDropdown ) searchDropdown . classList . remove ( 'show' ) ;
if ( buyDropdown ) buyDropdown . classList . remove ( 'show' ) ;
langDropdown . classList . toggle ( 'show' ) ;
if ( langDropdown . classList . contains ( 'show' ) ) {
openOverlay ( ) ;
} else {
closeOverlay ( ) ;
}
} ) ;
}
// 购买按钮点击
const buyWrapper = document . querySelector ( '.header-buy-wrapper' ) ;
if ( buyWrapper && buyDropdown ) {
buyWrapper . addEventListener ( 'click' , ( ) =>
{
// buyDropdown.classList.add('show');
buyWrapper . addEventListener ( 'click' , ( ) => {
buyDropdown . classList . toggle ( 'show' ) ;
if ( buyDropdown . classList . contains ( 'show' ) ) {
openOverlay ( ) ;
} else {
closeOverlay ( ) ;
}
} ) ;
}
document . addEventListener ( 'click' , ( e ) =>
{
// 全局点击关闭
document . addEventListener ( 'click' , ( e ) => {
if ( ! e . target . closest ( '.header-search-wrapper' ) ) {
if ( searchDropdown ) searchDropdown . classList . remove ( 'show' ) ;
}
@@ -452,414 +562,32 @@
if ( ! e . target . closest ( '.header-buy-wrapper' ) ) {
if ( buyDropdown ) buyDropdown . classList . remove ( 'show' ) ;
}
} ) ;
if ( searchDropdown ) searchDropdown . addEventListener ( 'click' , ( e ) => e . stopPropagation ( ) ) ;
if ( langDropdown ) langDropdown . addEventListener ( 'click' , ( e ) => e . stopPropagation ( ) ) ;
if ( buyDropdown ) buyDropdown . addEventListener ( 'click' , ( e ) => e . stopPropagation ( ) ) ;
renderHistory ( ) ;
// ========== 蒙版层功能(支持所有弹窗,包括导航悬停下拉) ==========
const mhk = document . getElementById ( 'mhk' ) ;
const body = document . body ;
// 获取滚动条宽度(防止打开弹窗时页面抖动)
function getScrollbarWidth ( ) {
const scrollDiv = document . createElement ( 'div' ) ;
scrollDiv . style . cssText = `
width: 100px;
height: 100px;
overflow: scroll;
position: absolute;
top: -9999px;
` ;
document . body . appendChild ( scrollDiv ) ;
const scrollbarWidth = scrollDiv . offsetWidth - scrollDiv . clientWidth ;
console . log ( scrollbarWidth , '=scrollbarWidth=' )
document . body . removeChild ( scrollDiv ) ;
return scrollbarWidth ;
}
// 打开蒙版层的函数
function openOverlay ( ) {
if ( mhk && mhk . style . display !== 'block' ) {
mhk . style . display = 'block' ;
body . style . overflow = 'hidden' ;
body . style . paddingRight = getScrollbarWidth ( ) + 'px' ;
}
}
// 关闭蒙版层的函数
function closeOverlay ( ) {
if ( mhk && mhk . style . display === 'block' ) {
// 检查是否还有其他弹窗打开(包括导航下拉菜单)
const isBuyOpen = buyDropdown && buyDropdown . classList . contains ( 'show' ) ;
const isSearchOpen = searchDropdown && searchDropdown . classList . contains ( 'show' ) ;
const isLangOpen = langDropdown && langDropdown . classList . contains ( 'show' ) ;
// 检查导航下拉菜单是否打开(通过检查是否有 active 或显示状态)
const productDropdown = document . querySelector ( '.header-nav-item:first-child .header-dropdown' ) ;
const isProductDropdownOpen = productDropdown && window . getComputedStyle ( productDropdown ) . display !== 'none' ;
// 检查其他导航下拉菜单
let isOtherNavOpen = false ;
const otherNavItems = document . querySelectorAll ( '.header-nav-item:not(:first-child)' ) ;
otherNavItems . forEach ( item => {
const dropdown = item . querySelector ( '.header-dropdown' ) ;
if ( dropdown && window . getComputedStyle ( dropdown ) . display !== 'none' ) {
isOtherNavOpen = true ;
}
} ) ;
// 只有当所有弹窗和导航下拉菜单都关闭时,才关闭蒙版层
if ( ! isBuyOpen && ! isSearchOpen && ! isLangOpen && ! isProductDropdownOpen && ! isOtherNavOpen ) {
mhk . style . display = 'none' ;
body . style . overflow = '' ;
body . style . paddingRight = '' ;
}
}
}
// 强制关闭所有弹窗和蒙版
function closeAllDropdownsAndOverlay ( ) {
let anyOpen = false ;
if ( buyDropdown && buyDropdown . classList . contains ( 'show' ) ) {
buyDropdown . classList . remove ( 'show' ) ;
anyOpen = true ;
}
if ( searchDropdown && searchDropdown . classList . contains ( 'show' ) ) {
searchDropdown . classList . remove ( 'show' ) ;
anyOpen = true ;
}
if ( langDropdown && langDropdown . classList . contains ( 'show' ) ) {
langDropdown . classList . remove ( 'show' ) ;
anyOpen = true ;
}
// 关闭产品列表导航的下拉菜单( 通过移除hover触发的显示)
const productNavItem = document . querySelector ( '.header-nav-item:first-child' ) ;
if ( productNavItem ) {
const productDropdown = productNavItem . querySelector ( '.header-dropdown' ) ;
if ( productDropdown && window . getComputedStyle ( productDropdown ) . display !== 'none' ) {
productDropdown . style . display = '' ;
anyOpen = true ;
}
}
// 关闭其他导航的下拉菜单
const otherNavItems = document . querySelectorAll ( '.header-nav-item:not(:first-child)' ) ;
otherNavItems . forEach ( item => {
const dropdown = item . querySelector ( '.header-dropdown' ) ;
if ( dropdown && window . getComputedStyle ( dropdown ) . display !== 'none' ) {
dropdown . style . display = '' ;
anyOpen = true ;
}
} ) ;
if ( anyOpen ) {
closeOverlay ( ) ;
} else {
closeOverlay ( ) ;
}
}
// ========== 监听导航下拉菜单的显示/隐藏 ==========
// 1. 产品列表导航(第一个导航项)
const productNavItem = document . querySelector ( '.header-nav-item:first-child' ) ;
if ( productNavItem ) {
const productDropdown = productNavItem . querySelector ( '.header-dropdown' ) ;
// 监听鼠标进入产品列表导航
productNavItem . addEventListener ( 'mouseenter' , ( ) => {
// 当导航下拉菜单显示时,关闭其他点击弹窗
if ( searchDropdown && searchDropdown . classList . contains ( 'show' ) ) {
searchDropdown . classList . remove ( 'show' ) ;
}
if ( langDropdown && langDropdown . classList . contains ( 'show' ) ) {
langDropdown . classList . remove ( 'show' ) ;
}
if ( buyDropdown && buyDropdown . classList . contains ( 'show' ) ) {
buyDropdown . classList . remove ( 'show' ) ;
}
// 打开蒙版层
openOverlay ( ) ;
} ) ;
// 监听鼠标离开产品列表导航(延迟关闭,给用户移动到下拉菜单的时间)
productNavItem . addEventListener ( 'mouseleave' , ( ) => {
setTimeout ( ( ) => {
// 检查鼠标是否在下拉菜单上
if ( productDropdown ) {
const isHoveringDropdown = productDropdown . matches ( ':hover' ) ;
const isHoveringNav = productNavItem . matches ( ':hover' ) ;
if ( ! isHoveringDropdown && ! isHoveringNav ) {
closeOverlay ( ) ;
}
} else {
closeOverlay ( ) ;
}
} , 100 ) ;
} ) ;
// 监听下拉菜单的鼠标离开事件
if ( productDropdown ) {
productDropdown . addEventListener ( 'mouseleave' , ( ) => {
setTimeout ( ( ) => {
const isHoveringNav = productNavItem . matches ( ':hover' ) ;
if ( ! isHoveringNav ) {
closeOverlay ( ) ;
}
} , 100 ) ;
} ) ;
}
}
// 2. 其他导航项(有下拉菜单的)
const otherNavItems = document . querySelectorAll ( '.header-nav-item:not(:first-child)' ) ;
otherNavItems . forEach ( item => {
const hasDropdown = item . querySelector ( '.header-dropdown' ) ;
if ( hasDropdown ) {
const dropdown = hasDropdown ;
// 监听鼠标进入导航项
item . addEventListener ( 'mouseenter' , ( ) => {
// 关闭其他点击弹窗
if ( searchDropdown && searchDropdown . classList . contains ( 'show' ) ) {
searchDropdown . classList . remove ( 'show' ) ;
}
if ( langDropdown && langDropdown . classList . contains ( 'show' ) ) {
langDropdown . classList . remove ( 'show' ) ;
}
if ( buyDropdown && buyDropdown . classList . contains ( 'show' ) ) {
buyDropdown . classList . remove ( 'show' ) ;
}
// 打开蒙版层
openOverlay ( ) ;
} ) ;
// 监听鼠标离开导航项
item . addEventListener ( 'mouseleave' , ( ) => {
setTimeout ( ( ) => {
if ( dropdown ) {
const isHoveringDropdown = dropdown . matches ( ':hover' ) ;
const isHoveringNav = item . matches ( ':hover' ) ;
if ( ! isHoveringDropdown && ! isHoveringNav ) {
closeOverlay ( ) ;
}
} else {
closeOverlay ( ) ;
}
} , 100 ) ;
} ) ;
// 监听下拉菜单的鼠标离开
if ( dropdown ) {
dropdown . addEventListener ( 'mouseleave' , ( ) => {
setTimeout ( ( ) => {
const isHoveringNav = item . matches ( ':hover' ) ;
if ( ! isHoveringNav ) {
closeOverlay ( ) ;
}
} , 100 ) ;
} ) ;
}
}
} ) ;
// ========== 重新绑定所有点击弹窗事件 ==========
// 1. 购买弹窗
const buyWrapperNew = document . querySelector ( '.header-buy-wrapper' ) ;
if ( buyWrapperNew && buyDropdown ) {
const newBuyWrapper = buyWrapperNew . cloneNode ( true ) ;
buyWrapperNew . parentNode . replaceChild ( newBuyWrapper , buyWrapperNew ) ;
newBuyWrapper . addEventListener ( 'click' , ( e ) => {
e . stopPropagation ( ) ;
const isOpen = buyDropdown . classList . contains ( 'show' ) ;
if ( isOpen ) {
buyDropdown . classList . remove ( 'show' ) ;
closeOverlay ( ) ;
} else {
// 关闭其他弹窗和导航下拉菜单
if ( searchDropdown && searchDropdown . classList . contains ( 'show' ) ) {
searchDropdown . classList . remove ( 'show' ) ;
}
if ( langDropdown && langDropdown . classList . contains ( 'show' ) ) {
langDropdown . classList . remove ( 'show' ) ;
}
// 关闭导航下拉菜单
closeAllNavDropdowns ( ) ;
buyDropdown . classList . add ( 'show' ) ;
openOverlay ( ) ;
}
} ) ;
}
// 2. 搜索弹窗
const searchBtnNew = document . querySelector ( '.header-search-wrapper .header-nav-btn' ) ;
if ( searchBtnNew && searchDropdown ) {
const newSearchBtn = searchBtnNew . cloneNode ( true ) ;
searchBtnNew . parentNode . replaceChild ( newSearchBtn , searchBtnNew ) ;
newSearchBtn . addEventListener ( 'click' , ( e ) => {
e . stopPropagation ( ) ;
const isOpen = searchDropdown . classList . contains ( 'show' ) ;
if ( isOpen ) {
searchDropdown . classList . remove ( 'show' ) ;
closeOverlay ( ) ;
} else {
// 关闭其他弹窗和导航下拉菜单
if ( buyDropdown && buyDropdown . classList . contains ( 'show' ) ) {
buyDropdown . classList . remove ( 'show' ) ;
}
if ( langDropdown && langDropdown . classList . contains ( 'show' ) ) {
langDropdown . classList . remove ( 'show' ) ;
}
// 关闭导航下拉菜单
closeAllNavDropdowns ( ) ;
searchDropdown . classList . add ( 'show' ) ;
openOverlay ( ) ;
if ( typeof renderHistory === 'function' ) {
renderHistory ( ) ;
}
}
} ) ;
}
// 3. 语言弹窗
const langBtnNew = document . querySelector ( '.header-lang-wrapper .header-nav-btn' ) ;
if ( langBtnNew && langDropdown ) {
const newLangBtn = langBtnNew . cloneNode ( true ) ;
langBtnNew . parentNode . replaceChild ( newLangBtn , langBtnNew ) ;
newLangBtn . addEventListener ( 'click' , ( e ) => {
e . stopPropagation ( ) ;
const isOpen = langDropdown . classList . contains ( 'show' ) ;
if ( isOpen ) {
langDropdown . classList . remove ( 'show' ) ;
closeOverlay ( ) ;
} else {
// 关闭其他弹窗和导航下拉菜单
if ( buyDropdown && buyDropdown . classList . contains ( 'show' ) ) {
buyDropdown . classList . remove ( 'show' ) ;
}
if ( searchDropdown && searchDropdown . classList . contains ( 'show' ) ) {
searchDropdown . classList . remove ( 'show' ) ;
}
// 关闭导航下拉菜单
closeAllNavDropdowns ( ) ;
langDropdown . classList . add ( 'show' ) ;
openOverlay ( ) ;
}
} ) ;
}
// 辅助函数:关闭所有导航下拉菜单
function closeAllNavDropdowns ( ) {
// 关闭产品列表导航下拉菜单
const productNavItem = document . querySelector ( '.header-nav-item:first-child' ) ;
if ( productNavItem ) {
const productDropdown = productNavItem . querySelector ( '.header-dropdown' ) ;
if ( productDropdown ) {
productDropdown . style . display = '' ;
}
}
// 关闭其他导航下拉菜单
const otherNavItems = document . querySelectorAll ( '.header-nav-item:not(:first-child)' ) ;
otherNavItems . forEach ( item => {
const dropdown = item . querySelector ( '.header-dropdown' ) ;
if ( dropdown ) {
dropdown . style . display = '' ;
}
} ) ;
}
// ========== 关闭按钮事件重新绑定 ==========
// 语言关闭按钮
const langCloseBtnNew = document . querySelector ( '.header-lang-dropdown-delete-icon' ) ;
if ( langCloseBtnNew && langDropdown ) {
const newLangCloseBtn = langCloseBtnNew . cloneNode ( true ) ;
langCloseBtnNew . parentNode . replaceChild ( newLangCloseBtn , langCloseBtnNew ) ;
newLangCloseBtn . addEventListener ( 'click' , ( e ) => {
e . stopPropagation ( ) ;
langDropdown . classList . remove ( 'show' ) ;
closeOverlay ( ) ;
} ) ;
}
// 搜索关闭按钮
const searchCloseBtnNew = document . querySelector ( '.header-search-dropdown-delete-icon' ) ;
if ( searchCloseBtnNew && searchDropdown ) {
const newSearchCloseBtn = searchCloseBtnNew . cloneNode ( true ) ;
searchCloseBtnNew . parentNode . replaceChild ( newSearchCloseBtn , searchCloseBtnNew ) ;
newSearchCloseBtn . addEventListener ( 'click' , ( e ) => {
e . stopPropagation ( ) ;
searchDropdown . classList . remove ( 'show' ) ;
closeOverlay ( ) ;
} ) ;
}
// ========== 全局点击事件 ==========
document . addEventListener ( 'click' , ( e ) => {
// 检查是否点击在购买区域外
if ( ! e . target . closest ( '.header-buy-wrapper' ) && ! e . target . closest ( '#buyDropdown' ) ) {
if ( buyDropdown && buyDropdown . classList . contains ( 'show' ) ) {
buyDropdown . classList . remove ( 'show' ) ;
closeOverlay ( ) ;
}
}
// 检查是否点击在搜索区域外
if ( ! e . target . closest ( '.header-search-wrapper' ) && ! e . target . closest ( '#searchDropdown' ) ) {
if ( searchDropdown && searchDropdown . classList . contains ( 'show' ) ) {
searchDropdown . classList . remove ( 'show' ) ;
closeOverlay ( ) ;
}
}
// 检查是否点击在语言区域外
if ( ! e . target . closest ( '.header-lang-wrapper' ) && ! e . target . closest ( '#langDropdown' ) ) {
if ( langDropdown && langDropdown . classList . contains ( 'show' ) ) {
langDropdown . classList . remove ( 'show' ) ;
closeOverlay ( ) ;
}
}
// 检查是否点击在导航区域外(如果点击在导航外部,关闭导航下拉菜单)
// 关闭所有导航下拉菜单
if ( ! e . target . closest ( '.header-nav-item' ) ) {
closeAllNavDropdowns ( ) ;
closeOverlay ( ) ;
}
} ) ;
// ========== 蒙版层点击事件 ==========
// 阻止弹窗冒泡
if ( searchDropdown ) searchDropdown . addEventListener ( 'click' , ( e ) => e . stopPropagation ( ) ) ;
if ( langDropdown ) langDropdown . addEventListener ( 'click' , ( e ) => e . stopPropagation ( ) ) ;
if ( buyDropdown ) buyDropdown . addEventListener ( 'click' , ( e ) => e . stopPropagation ( ) ) ;
// 蒙版层点击关闭
if ( mhk ) {
mhk . addEventListener ( 'click' , ( ) => {
closeAllDropdownsAndOverlay ( ) ;
if ( searchDropdown ) searchDropdown . classList . remove ( 'show' ) ;
if ( langDropdown ) langDropdown . classList . remove ( 'show' ) ;
if ( buyDropdown ) buyDropdown . classList . remove ( 'show' ) ;
closeAllNavDropdowns ( ) ;
closeOverlay ( ) ;
} ) ;
}
// ========== 监听弹窗状态变化 ==========
function setupDropdownObserver ( dropdown , name ) {
// 监听弹窗状态变化关闭蒙版
function setupDropdownObserver ( dropdown ) {
if ( ! dropdown ) return ;
const observer = new MutationObserver ( ( mutations ) => {
mutations . forEach ( ( mutation ) => {
if ( mutation . attributeName === 'class' ) {
@@ -872,18 +600,164 @@ function setupDropdownObserver(dropdown, name) {
observer . observe ( dropdown , { attributes : true } ) ;
}
setupDropdownObserver ( buyDropdown , 'buy' );
setupDropdownObserver ( searchDropdown , 'search' );
setupDropdownObserver ( langDropdown , 'lang' );
setupDropdownObserver ( buyDropdown ) ;
setupDropdownObserver ( searchDropdown ) ;
setupDropdownObserver ( langDropdown ) ;
// ========== 页面卸载时恢复滚动 ==========
window . addEventListener ( 'beforeunload' , ( ) => {
if ( body ) {
body . style . overflow = '' ;
body . style . paddingRight = '' ;
// ========== header-dropdown JS 控制版本(带防抖) ==========
function initHeaderDropdown ( ) {
const navItems = document . querySelectorAll ( '.header-nav-item' ) ;
let hoverTimer = null ;
let leaveTimer = null ;
let currentOpenDropdown = null ;
// 获取所有下拉菜单并设置初始状态
const allDropdowns = document . querySelectorAll ( '.header-dropdown' ) ;
allDropdowns . forEach ( dropdown => {
dropdown . style . opacity = '0' ;
dropdown . style . transform = 'translateY(-1.25em)' ;
dropdown . style . pointerEvents = 'none' ;
dropdown . style . transition = 'opacity 0.3s ease, transform 0.3s ease' ;
} ) ;
// 显示下拉菜单
function showDropdown ( dropdown ) {
if ( ! dropdown ) return ;
// 关闭当前打开的
if ( currentOpenDropdown && currentOpenDropdown !== dropdown ) {
hideDropdown ( currentOpenDropdown ) ;
}
dropdown . style . opacity = '1' ;
dropdown . style . transform = 'translateY(0)' ;
dropdown . style . pointerEvents = 'auto' ;
currentOpenDropdown = dropdown ;
}
// 隐藏下拉菜单
function hideDropdown ( dropdown ) {
if ( ! dropdown ) return ;
dropdown . style . opacity = '0' ;
dropdown . style . transform = 'translateY(-1.25em)' ;
dropdown . style . pointerEvents = 'none' ;
if ( currentOpenDropdown === dropdown ) {
currentOpenDropdown = null ;
}
}
// 隐藏所有下拉菜单
function hideAllDropdowns ( ) {
allDropdowns . forEach ( dropdown => {
dropdown . style . opacity = '0' ;
dropdown . style . transform = 'translateY(-1.25em)' ;
dropdown . style . pointerEvents = 'none' ;
} ) ;
currentOpenDropdown = null ;
}
navItems . forEach ( item => {
const dropdown = item . querySelector ( '.header-dropdown' ) ;
if ( ! dropdown ) return ;
// 鼠标移入导航项
item . addEventListener ( 'mouseenter' , ( ) => {
// 清除离开定时器
if ( leaveTimer ) clearTimeout ( leaveTimer ) ;
if ( hoverTimer ) clearTimeout ( hoverTimer ) ;
// 防抖: 延迟100ms再显示, 避免频繁触发
hoverTimer = setTimeout ( ( ) => {
// 关闭其他弹窗(搜索、语言、购买)
if ( searchDropdown ) searchDropdown . classList . remove ( 'show' ) ;
if ( langDropdown ) langDropdown . classList . remove ( 'show' ) ;
if ( buyDropdown ) buyDropdown . classList . remove ( 'show' ) ;
showDropdown ( dropdown ) ;
// 打开蒙版层
if ( typeof openOverlay === 'function' ) openOverlay ( ) ;
} , 100 ) ;
} ) ;
// 鼠标移出导航项
item . addEventListener ( 'mouseleave' , ( ) => {
// 清除移入定时器
if ( hoverTimer ) clearTimeout ( hoverTimer ) ;
// 延迟300ms再隐藏, 给用户移动到下拉菜单的时间
leaveTimer = setTimeout ( ( ) => {
// 检查鼠标是否在下拉菜单上
const isHoveringDropdown = dropdown . matches ( ':hover' ) ;
if ( ! isHoveringDropdown ) {
hideDropdown ( dropdown ) ;
// 关闭蒙版层
if ( typeof closeOverlay === 'function' ) closeOverlay ( ) ;
}
} , 300 ) ;
} ) ;
// 鼠标移入下拉菜单
dropdown . addEventListener ( 'mouseenter' , ( ) => {
if ( leaveTimer ) clearTimeout ( leaveTimer ) ;
showDropdown ( dropdown ) ;
} ) ;
// 鼠标移出下拉菜单
dropdown . addEventListener ( 'mouseleave' , ( ) => {
leaveTimer = setTimeout ( ( ) => {
const isHoveringNav = item . matches ( ':hover' ) ;
if ( ! isHoveringNav ) {
hideDropdown ( dropdown ) ;
// 关闭蒙版层
if ( typeof closeOverlay === 'function' ) closeOverlay ( ) ;
}
} , 200 ) ;
} ) ;
} ) ;
// 点击其他地方关闭所有下拉菜单
document . addEventListener ( 'click' , ( e ) => {
if ( ! e . target . closest ( '.header-nav-item' ) ) {
hideAllDropdowns ( ) ;
if ( typeof closeOverlay === 'function' ) closeOverlay ( ) ;
}
} ) ;
// 确保蒙版层初始状态正确
// 暴露方法供外部调用
window . headerDropdown = {
hideAll : hideAllDropdowns ,
show : showDropdown ,
hide : hideDropdown
} ;
}
// 初始化(在 DOM 加载完成后执行)
if ( document . readyState === 'loading' ) {
document . addEventListener ( 'DOMContentLoaded' , initHeaderDropdown ) ;
} else {
initHeaderDropdown ( ) ;
}
// 页面卸载时恢复滚动
window . addEventListener ( 'beforeunload' , ( ) => {
if ( body ) {
body . style . position = '' ;
body . style . top = '' ;
body . style . left = '' ;
body . style . right = '' ;
body . style . width = '' ;
}
} ) ;
// 初始化导航下拉菜单蒙版层
initNavDropdownOverlay ( ) ;
// 初始化渲染
renderHistory ( ) ;
closeOverlay ( ) ;
< / script >