diff --git a/common/common.js b/common/common.js index a7cd4e0..0ee410f 100644 --- a/common/common.js +++ b/common/common.js @@ -127,50 +127,76 @@ $(function () { }; function initHeader() { let showIndex = 0; + let hoverTimer = null; + let leaveTimer = null; + $(".nav-menu .nav-item").hover( function () { const index = $(".nav-menu .nav-item").index($(this)); - $(".nav-cont .nav-cont-menu") - .eq(index) - .attr("style", "display: block;"); - - // $('.nav-cont').attr('style','display: block;') - if ( - !$(".nav-cont .nav-cont-menu").eq(index).hasClass("nav-cont-empty") - ) { - const height = $(".nav-cont .nav-cont-menu").eq(index).height(); - $(".nav-cont").attr("style", `height: ${height}px;`); + + // 清除离开定时器 + if (leaveTimer) { + clearTimeout(leaveTimer); + leaveTimer = null; } - showIndex = index; + + // 添加150ms延迟,防止误触 + hoverTimer = setTimeout(() => { + $(".nav-cont .nav-cont-menu") + .eq(index) + .css("display", "block"); + + if ( + !$(".nav-cont .nav-cont-menu").eq(index).hasClass("nav-cont-empty") + ) { + const height = $(".nav-cont .nav-cont-menu").eq(index).outerHeight(true); + $(".nav-cont").css("height", height + "px"); + } + showIndex = index; + }, 150); }, function () { - const index = $(".nav-menu .nav-item").index($(this)); - $(".nav-cont ").eq(index).attr("style", "display: none;"); - $(".nav-cont .nav-cont-menu").eq(index).attr("style", "display: none;"); - $(".nav-cont").attr("style", "height:0"); + // 清除悬停定时器 + if (hoverTimer) { + clearTimeout(hoverTimer); + hoverTimer = null; + } + + leaveTimer = setTimeout(() => { + const index = $(".nav-menu .nav-item").index($(this)); + $(".nav-cont .nav-cont-menu").eq(index).css("display", "none"); + $(".nav-cont").css("height", "0"); + }, 100); } ); $(".nav-cont").hover( function () { - //$('.nav-cont ').attr('style','display: block;') + // 清除离开定时器 + if (leaveTimer) { + clearTimeout(leaveTimer); + leaveTimer = null; + } + $(".nav-cont .nav-cont-menu") .eq(showIndex) - .attr("style", "display: block;"); - //if (showIndex != 0) { - if (!$(this).hasClass("nav-cont-empty")) { - const height = $(".nav-cont .nav-cont-menu").eq(showIndex).height(); - $(".nav-cont").attr("style", `height: ${height}px;`); + .css("display", "block"); + + if (!$(".nav-cont .nav-cont-menu").eq(showIndex).hasClass("nav-cont-empty")) { + const height = $(".nav-cont .nav-cont-menu").eq(showIndex).outerHeight(true); + $(".nav-cont").css("height", height + "px"); } }, function () { - //$('.nav-cont ').attr('style','display: none;') - $(".nav-cont .nav-cont-menu") - .eq(showIndex) - .attr("style", "display: none;"); - $(".nav-cont").attr("style", "height:0"); + leaveTimer = setTimeout(() => { + $(".nav-cont .nav-cont-menu") + .eq(showIndex) + .css("display", "none"); + $(".nav-cont").css("height", "0"); + }, 100); } ); + if (localStorage.jwt) { if (sessionStorage.accountInfo) { const obj = JSON.parse(sessionStorage.accountInfo); diff --git a/css/nav-mega-menu.css b/css/nav-mega-menu.css new file mode 100644 index 0000000..b2c333d --- /dev/null +++ b/css/nav-mega-menu.css @@ -0,0 +1,222 @@ +/* 三级导航菜单样式 - Mega Menu风格 */ + +/* 导航容器 */ +.nav-cont { + position: absolute; + top: 100%; + left: 0; + width: 100%; + background: #fff; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); + z-index: 1000; + overflow: hidden; + transition: height 0.3s ease-out; +} + +/* Mega Menu 内容区 */ +.nav-cont-menu.mega-menu { + display: none; + padding: 24px 0; +} + +.nav-cont-menu.mega-menu .nav-content { + display: flex; + flex-wrap: wrap; + gap: 32px; + max-width: 1400px; + margin: 0 auto; + padding: 0 20px; +} + +/* 二级菜单项(带三级菜单的分类) */ +.nav-category { + flex: 0 0 auto; + min-width: 200px; + max-width: 280px; +} + +.nav-category-header { + display: flex; + align-items: center; + gap: 12px; + padding: 8px 12px; + margin-bottom: 12px; + border-radius: 6px; + background: linear-gradient(135deg, #f0f7ff 0%, #e6f3ff 100%); + transition: all 0.2s ease; +} + +.nav-category-header:hover { + background: linear-gradient(135deg, #e6f3ff 0%, #d9edff 100%); + transform: translateX(2px); +} + +.nav-category-icon { + flex-shrink: 0; + width: 32px; + height: 32px; + border-radius: 6px; + overflow: hidden; +} + +.nav-category-icon img { + width: 100%; + height: 100%; + object-fit: contain; +} + +.nav-category-info { + flex: 1; + min-width: 0; +} + +.nav-category-title { + font-size: 14px; + font-weight: 600; + color: #1890ff; + margin-bottom: 2px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.nav-category-desc { + font-size: 12px; + color: #8c8c8c; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +/* 三级菜单列表 */ +.nav-third-level { + padding-left: 12px; +} + +.nav-third-item { + margin-bottom: 8px; +} + +.nav-third-link { + display: flex; + align-items: center; + gap: 8px; + padding: 6px 12px; + border-radius: 4px; + color: #333; + font-size: 13px; + text-decoration: none; + transition: all 0.2s ease; + position: relative; +} + +.nav-third-link::before { + content: ''; + position: absolute; + left: 0; + top: 50%; + transform: translateY(-50%); + width: 3px; + height: 0; + background: #1890ff; + border-radius: 2px; + transition: height 0.2s ease; +} + +.nav-third-link:hover { + background: #f5f5f5; + color: #1890ff; + padding-left: 16px; +} + +.nav-third-link:hover::before { + height: 16px; +} + +.nav-third-name { + flex: 1; + font-weight: 500; +} + +.nav-third-desc { + font-size: 11px; + color: #999; + margin-left: auto; +} + +/* 没有三级菜单的二级菜单项(旧版兼容) */ +.nav-item-box { + display: flex; + align-items: flex-start; + gap: 12px; + padding: 12px 16px; + border-radius: 6px; + transition: all 0.2s ease; + text-decoration: none; + color: #333; +} + +.nav-item-box:hover { + background: #f5f5f5; + transform: translateY(-2px); +} + +.nav-item-box img { + width: 40px; + height: 40px; + flex-shrink: 0; + border-radius: 4px; +} + +.item-box-title .title { + font-size: 14px; + font-weight: 600; + color: #333; + margin-bottom: 4px; +} + +.item-box-title .desc { + font-size: 12px; + color: #8c8c8c; +} + +/* 空菜单占位 */ +.nav-cont-menu.nav-cont-empty { + display: none; +} + +/* 响应式调整 */ +@media (max-width: 768px) { + .nav-cont { + display: none !important; + } + + .nav-cont-menu.mega-menu { + padding: 16px 0; + } + + .nav-cont-menu.mega-menu .nav-content { + flex-direction: column; + gap: 16px; + } + + .nav-category { + max-width: 100%; + } +} + +/* 加载动画 */ +@keyframes fadeInDown { + from { + opacity: 0; + transform: translateY(-10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.nav-cont-menu.animated { + animation: fadeInDown 0.3s ease-out; +} diff --git a/header.html b/header.html index 5c74ad0..24d8dfe 100644 --- a/header.html +++ b/header.html @@ -2,112 +2,113 @@
- {php} - // 在渲染阶段从主题配置插件读取配置,并覆盖 $data 与 SEO 变量,实现 SSR - if (class_exists('\\addon\\theme_configurator\\model\\ThemeConfigModel')) { - $cfgModel = new \addon\theme_configurator\model\ThemeConfigModel(); - $themeCfg = $cfgModel->getConfig(); + {php} + // 在渲染阶段从主题配置插件读取配置,并覆盖 $data 与 SEO 变量,实现 SSR + if (class_exists('\\addon\\theme_configurator\\model\\ThemeConfigModel')) { + $cfgModel = new \addon\theme_configurator\model\ThemeConfigModel(); + $themeCfg = $cfgModel->getConfig(); - if (is_array($themeCfg)) { - $site = isset($themeCfg['site_config']) && is_array($themeCfg['site_config']) - ? $themeCfg['site_config'] - : []; + if (is_array($themeCfg)) { + $site = isset($themeCfg['site_config']) && is_array($themeCfg['site_config']) + ? $themeCfg['site_config'] + : []; - if (!isset($data) || !is_array($data)) { - $data = []; - } + if (!isset($data) || !is_array($data)) { + $data = []; + } - // 覆盖 / 补充首页相关结构数据 - if (isset($themeCfg['banner'])) { - $data['banner'] = $themeCfg['banner']; - } - if (isset($themeCfg['honor'])) { - $data['honor'] = $themeCfg['honor']; - } - if (isset($themeCfg['friendly_link'])) { - $data['friendly_link'] = $themeCfg['friendly_link']; - } - if (isset($themeCfg['header_nav'])) { - $data['header_nav'] = $themeCfg['header_nav']; - } - if (isset($themeCfg['footer_nav'])) { - $data['footer_nav'] = $themeCfg['footer_nav']; - } - if (isset($themeCfg['side'])) { - $data['side_floating_window'] = $themeCfg['side']; - } + // 覆盖 / 补充首页相关结构数据 + if (isset($themeCfg['banner'])) { + $data['banner'] = $themeCfg['banner']; + } + if (isset($themeCfg['honor'])) { + $data['honor'] = $themeCfg['honor']; + } + if (isset($themeCfg['friendly_link'])) { + $data['friendly_link'] = $themeCfg['friendly_link']; + } + if (isset($themeCfg['header_nav'])) { + $data['header_nav'] = $themeCfg['header_nav']; + } + if (isset($themeCfg['footer_nav'])) { + $data['footer_nav'] = $themeCfg['footer_nav']; + } + if (isset($themeCfg['side'])) { + $data['side_floating_window'] = $themeCfg['side']; + } - // 站点基础信息,供 header/footer 与其他模板直接使用 - $data['enterprise_name'] = $site['enterprise_name'] ?? ($data['enterprise_name'] ?? ''); - $data['enterprise_telephone'] = $site['enterprise_telephone'] ?? ($data['enterprise_telephone'] ?? ''); - $data['enterprise_mailbox'] = $site['enterprise_mailbox'] ?? ($data['enterprise_mailbox'] ?? ''); - $data['enterprise_qrcode'] = $site['enterprise_qrcode'] ?? ($data['enterprise_qrcode'] ?? ''); - $data['official_website_logo']= $site['official_website_logo']?? ($data['official_website_logo']?? ''); - $data['online_customer_service_link'] = - $site['online_customer_service_link'] ?? ($data['online_customer_service_link'] ?? ''); - $data['icp_info'] = $site['icp_info'] ?? ($data['icp_info'] ?? ''); - $data['icp_info_link'] = $site['icp_info_link'] ?? ($data['icp_info_link'] ?? ''); - $data['public_security_network_preparation'] = - $site['public_security_network_preparation'] ?? - ($data['public_security_network_preparation'] ?? ''); - $data['public_security_network_preparation_link'] = - $site['public_security_network_preparation_link'] ?? - ($data['public_security_network_preparation_link'] ?? ''); - $data['telecom_appreciation'] = $site['telecom_appreciation'] ?? ($data['telecom_appreciation'] ?? ''); - $data['copyright_info'] = $site['copyright_info'] ?? ($data['copyright_info'] ?? ''); - $data['terms_service_url'] = $site['terms_service_url'] ?? ($data['terms_service_url'] ?? ''); - $data['terms_privacy_url'] = $site['terms_privacy_url'] ?? ($data['terms_privacy_url'] ?? ''); - $data['cloud_product_link'] = $site['cloud_product_link'] ?? ($data['cloud_product_link'] ?? ''); - $data['dcim_product_link'] = $site['dcim_product_link'] ?? ($data['dcim_product_link'] ?? ''); + // 站点基础信息,供 header/footer 与其他模板直接使用 + $data['enterprise_name'] = $site['enterprise_name'] ?? ($data['enterprise_name'] ?? ''); + $data['enterprise_telephone'] = $site['enterprise_telephone'] ?? ($data['enterprise_telephone'] ?? ''); + $data['enterprise_mailbox'] = $site['enterprise_mailbox'] ?? ($data['enterprise_mailbox'] ?? ''); + $data['enterprise_qrcode'] = $site['enterprise_qrcode'] ?? ($data['enterprise_qrcode'] ?? ''); + $data['official_website_logo']= $site['official_website_logo']?? ($data['official_website_logo']?? ''); + $data['online_customer_service_link'] = + $site['online_customer_service_link'] ?? ($data['online_customer_service_link'] ?? ''); + $data['icp_info'] = $site['icp_info'] ?? ($data['icp_info'] ?? ''); + $data['icp_info_link'] = $site['icp_info_link'] ?? ($data['icp_info_link'] ?? ''); + $data['public_security_network_preparation'] = + $site['public_security_network_preparation'] ?? + ($data['public_security_network_preparation'] ?? ''); + $data['public_security_network_preparation_link'] = + $site['public_security_network_preparation_link'] ?? + ($data['public_security_network_preparation_link'] ?? ''); + $data['telecom_appreciation'] = $site['telecom_appreciation'] ?? ($data['telecom_appreciation'] ?? ''); + $data['copyright_info'] = $site['copyright_info'] ?? ($data['copyright_info'] ?? ''); + $data['terms_service_url'] = $site['terms_service_url'] ?? ($data['terms_service_url'] ?? ''); + $data['terms_privacy_url'] = $site['terms_privacy_url'] ?? ($data['terms_privacy_url'] ?? ''); + $data['cloud_product_link'] = $site['cloud_product_link'] ?? ($data['cloud_product_link'] ?? ''); + $data['dcim_product_link'] = $site['dcim_product_link'] ?? ($data['dcim_product_link'] ?? ''); - // SEO:如插件配置了 SEO,则覆盖控制器传入的标题/关键词/描述 - if (!empty($themeCfg['seo']['title'])) { - $title = $themeCfg['seo']['title']; - } - if (!empty($themeCfg['seo']['keywords'])) { - $keywords = $themeCfg['seo']['keywords']; - } - if (!empty($themeCfg['seo']['description'])) { - $description = $themeCfg['seo']['description']; - } - } - } - {/php} + // SEO:如插件配置了 SEO,则覆盖控制器传入的标题/关键词/描述 + if (!empty($themeCfg['seo']['title'])) { + $title = $themeCfg['seo']['title']; + } + if (!empty($themeCfg['seo']['keywords'])) { + $keywords = $themeCfg['seo']['keywords']; + } + if (!empty($themeCfg['seo']['description'])) { + $description = $themeCfg['seo']['description']; + } + } + } + {/php} - -