Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8daf4d0696 | |||
| 2b2dc2021a | |||
| 654caf58c2 | |||
| 49240893b5 | |||
| f4646f1e3a | |||
| 624d7fde2f | |||
| a85f2c1b3a | |||
| 67016c4e9a | |||
| 12bc6aeee7 | |||
| 24e5554bc4 | |||
| c767c20641 | |||
| 2c85df4a98 | |||
| 88a91f3136 | |||
| 5fd603cbc6 | |||
| b92753c822 | |||
| ddd578eb08 | |||
| 1cdd0536b9 | |||
| 9cc6dc3cd9 | |||
| 4d25f6fec8 | |||
| 2764ce3b86 | |||
| 7cb270b313 | |||
| 86ffcb99ac | |||
| c476193002 | |||
| 5643faad94 | |||
| 989f6c25a0 | |||
| 2e5103b19a |
208
LICENSE
Normal file
208
LICENSE
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
Apache License
|
||||||
|
|
||||||
|
Version 2.0, January 2004
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION,
|
||||||
|
AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction, and distribution
|
||||||
|
as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by the copyright
|
||||||
|
owner that is granting the License.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all other entities
|
||||||
|
that control, are controlled by, or are under common control with that entity.
|
||||||
|
For the purposes of this definition, "control" means (i) the power, direct
|
||||||
|
or indirect, to cause the direction or management of such entity, whether
|
||||||
|
by contract or otherwise, or (ii) ownership of fifty percent (50%) or more
|
||||||
|
of the outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions
|
||||||
|
granted by this License.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications, including
|
||||||
|
but not limited to software source code, documentation source, and configuration
|
||||||
|
files.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical transformation
|
||||||
|
or translation of a Source form, including but not limited to compiled object
|
||||||
|
code, generated documentation, and conversions to other media types.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or Object form,
|
||||||
|
made available under the License, as indicated by a copyright notice that
|
||||||
|
is included in or attached to the work (an example is provided in the Appendix
|
||||||
|
below).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object form,
|
||||||
|
that is based on (or derived from) the Work and for which the editorial revisions,
|
||||||
|
annotations, elaborations, or other modifications represent, as a whole, an
|
||||||
|
original work of authorship. For the purposes of this License, Derivative
|
||||||
|
Works shall not include works that remain separable from, or merely link (or
|
||||||
|
bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including the original version
|
||||||
|
of the Work and any modifications or additions to that Work or Derivative
|
||||||
|
Works thereof, that is intentionally submitted to Licensor for inclusion in
|
||||||
|
the Work by the copyright owner or by an individual or Legal Entity authorized
|
||||||
|
to submit on behalf of the copyright owner. For the purposes of this definition,
|
||||||
|
"submitted" means any form of electronic, verbal, or written communication
|
||||||
|
sent to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems, and
|
||||||
|
issue tracking systems that are managed by, or on behalf of, the Licensor
|
||||||
|
for the purpose of discussing and improving the Work, but excluding communication
|
||||||
|
that is conspicuously marked or otherwise designated in writing by the copyright
|
||||||
|
owner as "Not a Contribution."
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
|
||||||
|
of whom a Contribution has been received by Licensor and subsequently incorporated
|
||||||
|
within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of this
|
||||||
|
License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||||
|
no-charge, royalty-free, irrevocable copyright license to reproduce, prepare
|
||||||
|
Derivative Works of, publicly display, publicly perform, sublicense, and distribute
|
||||||
|
the Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of this License,
|
||||||
|
each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||||
|
no-charge, royalty-free, irrevocable (except as stated in this section) patent
|
||||||
|
license to make, have made, use, offer to sell, sell, import, and otherwise
|
||||||
|
transfer the Work, where such license applies only to those patent claims
|
||||||
|
licensable by such Contributor that are necessarily infringed by their Contribution(s)
|
||||||
|
alone or by combination of their Contribution(s) with the Work to which such
|
||||||
|
Contribution(s) was submitted. If You institute patent litigation against
|
||||||
|
any entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||||
|
that the Work or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses granted to You
|
||||||
|
under this License for that Work shall terminate as of the date such litigation
|
||||||
|
is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the Work or
|
||||||
|
Derivative Works thereof in any medium, with or without modifications, and
|
||||||
|
in Source or Object form, provided that You meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or Derivative Works a copy
|
||||||
|
of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices stating that
|
||||||
|
You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works that You distribute,
|
||||||
|
all copyright, patent, trademark, and attribution notices from the Source
|
||||||
|
form of the Work, excluding those notices that do not pertain to any part
|
||||||
|
of the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its distribution,
|
||||||
|
then any Derivative Works that You distribute must include a readable copy
|
||||||
|
of the attribution notices contained within such NOTICE file, excluding those
|
||||||
|
notices that do not pertain to any part of the Derivative Works, in at least
|
||||||
|
one of the following places: within a NOTICE text file distributed as part
|
||||||
|
of the Derivative Works; within the Source form or documentation, if provided
|
||||||
|
along with the Derivative Works; or, within a display generated by the Derivative
|
||||||
|
Works, if and wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and do not modify the
|
||||||
|
License. You may add Your own attribution notices within Derivative Works
|
||||||
|
that You distribute, alongside or as an addendum to the NOTICE text from the
|
||||||
|
Work, provided that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and may provide
|
||||||
|
additional or different license terms and conditions for use, reproduction,
|
||||||
|
or distribution of Your modifications, or for any such Derivative Works as
|
||||||
|
a whole, provided Your use, reproduction, and distribution of the Work otherwise
|
||||||
|
complies with the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise, any
|
||||||
|
Contribution intentionally submitted for inclusion in the Work by You to the
|
||||||
|
Licensor shall be under the terms and conditions of this License, without
|
||||||
|
any additional terms or conditions. Notwithstanding the above, nothing herein
|
||||||
|
shall supersede or modify the terms of any separate license agreement you
|
||||||
|
may have executed with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade names,
|
||||||
|
trademarks, service marks, or product names of the Licensor, except as required
|
||||||
|
for reasonable and customary use in describing the origin of the Work and
|
||||||
|
reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or agreed to
|
||||||
|
in writing, Licensor provides the Work (and each Contributor provides its
|
||||||
|
Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied, including, without limitation, any warranties
|
||||||
|
or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness
|
||||||
|
of using or redistributing the Work and assume any risks associated with Your
|
||||||
|
exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory, whether
|
||||||
|
in tort (including negligence), contract, or otherwise, unless required by
|
||||||
|
applicable law (such as deliberate and grossly negligent acts) or agreed to
|
||||||
|
in writing, shall any Contributor be liable to You for damages, including
|
||||||
|
any direct, indirect, special, incidental, or consequential damages of any
|
||||||
|
character arising as a result of this License or out of the use or inability
|
||||||
|
to use the Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all other commercial
|
||||||
|
damages or losses), even if such Contributor has been advised of the possibility
|
||||||
|
of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing the Work
|
||||||
|
or Derivative Works thereof, You may choose to offer, and charge a fee for,
|
||||||
|
acceptance of support, warranty, indemnity, or other liability obligations
|
||||||
|
and/or rights consistent with this License. However, in accepting such obligations,
|
||||||
|
You may act only on Your own behalf and on Your sole responsibility, not on
|
||||||
|
behalf of any other Contributor, and only if You agree to indemnify, defend,
|
||||||
|
and hold each Contributor harmless for any liability incurred by, or claims
|
||||||
|
asserted against, such Contributor by reason of your accepting any such warranty
|
||||||
|
or additional liability. END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following boilerplate
|
||||||
|
notice, with the fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
information. (Don't include the brackets!) The text should be enclosed in
|
||||||
|
the appropriate comment syntax for the file format. We also recommend that
|
||||||
|
a file or class name and description of purpose be included on the same "printed
|
||||||
|
page" as the copyright notice for easier identification within third-party
|
||||||
|
archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
|
||||||
|
limitations under the License.
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
<div class="header-nav-item" >
|
<div class="header-nav-item" >
|
||||||
<div class="header-nav-title">{:lang_i18n('产品列表')}</div>
|
<div class="header-nav-title">{:lang_i18n('产品列表')}</div>
|
||||||
<!-- style=" opacity: 1;" -->
|
<!-- style=" opacity: 1;" -->
|
||||||
<div class="header-dropdown" style=" opacity: 1;">
|
<div class="header-dropdown" >
|
||||||
<div class="header-dropdown-tabs">
|
<div class="header-dropdown-tabs">
|
||||||
{volist name="header_categorys" id="vo" key="idx"}
|
{volist name="header_categorys" id="vo" key="idx"}
|
||||||
<a href="{:url('product/category', ['id' => $vo.id])}" class="header-tab-item {if condition="$idx == 1"}active{/if}" data-tab="tag-{$vo.id}">{$vo.name}</a>
|
<a href="{:url('product/category', ['id' => $vo.id])}" class="header-tab-item {if condition="$idx == 1"}active{/if}" data-tab="tag-{$vo.id}">{$vo.name}</a>
|
||||||
@@ -350,6 +350,7 @@
|
|||||||
if (mhk && mhk.style.display !== 'block') {
|
if (mhk && mhk.style.display !== 'block') {
|
||||||
// 保存当前滚动位置
|
// 保存当前滚动位置
|
||||||
scrollTopPosition = window.pageYOffset || document.documentElement.scrollTop;
|
scrollTopPosition = window.pageYOffset || document.documentElement.scrollTop;
|
||||||
|
|
||||||
mhk.style.display = 'block';
|
mhk.style.display = 'block';
|
||||||
|
|
||||||
// 禁止滚动,保持位置
|
// 禁止滚动,保持位置
|
||||||
@@ -376,18 +377,76 @@
|
|||||||
hasNavOpen = true;
|
hasNavOpen = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!isBuyOpen && !isSearchOpen && !isLangOpen && !hasNavOpen) {
|
||||||
mhk.style.display = 'none';
|
mhk.style.display = 'none';
|
||||||
|
|
||||||
// 恢复滚动
|
// 恢复滚动
|
||||||
body.style.position = '';
|
body.style.position = '';
|
||||||
body.style.top = '';
|
body.style.top = '';
|
||||||
body.style.left = '';
|
body.style.left = '';
|
||||||
body.style.right = '';
|
body.style.right = '';
|
||||||
body.style.width = '';
|
body.style.width = '';
|
||||||
|
|
||||||
// 恢复滚动位置
|
// 恢复滚动位置
|
||||||
window.scrollTo(0, scrollTopPosition);
|
window.scrollTo(0, scrollTopPosition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========== header-dropdown 导航下拉菜单打开时显示蒙版 ==========
|
||||||
|
function initNavDropdownOverlay() {
|
||||||
|
const navItems = document.querySelectorAll('.header-nav-item');
|
||||||
|
let hideTimer = null;
|
||||||
|
|
||||||
|
navItems.forEach(item => {
|
||||||
|
const dropdown = item.querySelector('.header-dropdown');
|
||||||
|
if (!dropdown) return;
|
||||||
|
|
||||||
|
// 鼠标移入导航项
|
||||||
|
item.addEventListener('mouseenter', () => {
|
||||||
|
if (hideTimer) clearTimeout(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() {
|
function closeAllNavDropdowns() {
|
||||||
document.querySelectorAll('.header-dropdown').forEach(dropdown => {
|
document.querySelectorAll('.header-dropdown').forEach(dropdown => {
|
||||||
@@ -545,13 +604,15 @@
|
|||||||
setupDropdownObserver(searchDropdown);
|
setupDropdownObserver(searchDropdown);
|
||||||
setupDropdownObserver(langDropdown);
|
setupDropdownObserver(langDropdown);
|
||||||
|
|
||||||
// ========== 监听下拉菜单打开状态,自动控制蒙版 ==========
|
// ========== header-dropdown JS 控制版本(带防抖) ==========
|
||||||
|
|
||||||
function initHeaderDropdown() {
|
function initHeaderDropdown() {
|
||||||
// 获取所有下拉菜单
|
const navItems = document.querySelectorAll('.header-nav-item');
|
||||||
const allDropdowns = document.querySelectorAll('.header-dropdown');
|
let hoverTimer = null;
|
||||||
|
let leaveTimer = null;
|
||||||
|
let currentOpenDropdown = null;
|
||||||
|
|
||||||
// 设置初始样式
|
// 获取所有下拉菜单并设置初始状态
|
||||||
|
const allDropdowns = document.querySelectorAll('.header-dropdown');
|
||||||
allDropdowns.forEach(dropdown => {
|
allDropdowns.forEach(dropdown => {
|
||||||
dropdown.style.opacity = '0';
|
dropdown.style.opacity = '0';
|
||||||
dropdown.style.transform = 'translateY(-1.25em)';
|
dropdown.style.transform = 'translateY(-1.25em)';
|
||||||
@@ -559,110 +620,115 @@
|
|||||||
dropdown.style.transition = 'opacity 0.3s ease, transform 0.3s ease';
|
dropdown.style.transition = 'opacity 0.3s ease, transform 0.3s ease';
|
||||||
});
|
});
|
||||||
|
|
||||||
// 监听单个下拉菜单的样式变化
|
// 显示下拉菜单
|
||||||
function observeDropdown(dropdown) {
|
function showDropdown(dropdown) {
|
||||||
const observer = new MutationObserver(() => {
|
if (!dropdown) return;
|
||||||
const isOpen = dropdown.style.opacity === '1';
|
// 关闭当前打开的
|
||||||
if (isOpen) {
|
if (currentOpenDropdown && currentOpenDropdown !== dropdown) {
|
||||||
openOverlay();
|
hideDropdown(currentOpenDropdown);
|
||||||
} else {
|
}
|
||||||
let anyOpen = false;
|
dropdown.style.opacity = '1';
|
||||||
allDropdowns.forEach(d => {
|
dropdown.style.transform = 'translateY(0)';
|
||||||
if (d.style.opacity === '1') anyOpen = true;
|
dropdown.style.pointerEvents = 'auto';
|
||||||
});
|
currentOpenDropdown = dropdown;
|
||||||
if (!anyOpen) {
|
|
||||||
closeOverlay();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
observer.observe(dropdown, {
|
|
||||||
attributes: true,
|
|
||||||
attributeFilter: ['style']
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 为每个下拉菜单添加监听
|
// 隐藏下拉菜单
|
||||||
allDropdowns.forEach(dropdown => {
|
function hideDropdown(dropdown) {
|
||||||
observeDropdown(dropdown);
|
if (!dropdown) return;
|
||||||
});
|
dropdown.style.opacity = '0';
|
||||||
|
dropdown.style.transform = 'translateY(-1.25em)';
|
||||||
|
dropdown.style.pointerEvents = 'none';
|
||||||
|
if (currentOpenDropdown === dropdown) {
|
||||||
|
currentOpenDropdown = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 鼠标悬停控制下拉菜单显示/隐藏
|
// 隐藏所有下拉菜单
|
||||||
const navItems = document.querySelectorAll('.header-nav-item');
|
function hideAllDropdowns() {
|
||||||
|
allDropdowns.forEach(dropdown => {
|
||||||
|
dropdown.style.opacity = '0';
|
||||||
|
dropdown.style.transform = 'translateY(-1.25em)';
|
||||||
|
dropdown.style.pointerEvents = 'none';
|
||||||
|
});
|
||||||
|
currentOpenDropdown = null;
|
||||||
|
}
|
||||||
|
|
||||||
navItems.forEach(item => {
|
navItems.forEach(item => {
|
||||||
const dropdown = item.querySelector('.header-dropdown');
|
const dropdown = item.querySelector('.header-dropdown');
|
||||||
if (!dropdown) return;
|
if (!dropdown) return;
|
||||||
|
|
||||||
let timer = null;
|
// 鼠标移入导航项
|
||||||
let isHovering = false; // 增加悬停状态标记
|
|
||||||
|
|
||||||
// 显示下拉菜单的函数
|
|
||||||
const showDropdown = () => {
|
|
||||||
if (timer) clearTimeout(timer);
|
|
||||||
if (dropdown.style.opacity === '1') return;
|
|
||||||
dropdown.style.opacity = '1';
|
|
||||||
dropdown.style.transform = 'translateY(0)';
|
|
||||||
dropdown.style.pointerEvents = 'auto';
|
|
||||||
};
|
|
||||||
|
|
||||||
// 隐藏下拉菜单的函数
|
|
||||||
const hideDropdown = () => {
|
|
||||||
if (timer) clearTimeout(timer);
|
|
||||||
if (dropdown.style.opacity === '0') return;
|
|
||||||
dropdown.style.opacity = '0';
|
|
||||||
dropdown.style.transform = 'translateY(-1.25em)';
|
|
||||||
dropdown.style.pointerEvents = 'none';
|
|
||||||
};
|
|
||||||
|
|
||||||
item.addEventListener('mouseenter', () => {
|
item.addEventListener('mouseenter', () => {
|
||||||
isHovering = true;
|
// 清除离开定时器
|
||||||
clearTimeout(timer);
|
if (leaveTimer) clearTimeout(leaveTimer);
|
||||||
showDropdown();
|
if (hoverTimer) clearTimeout(hoverTimer);
|
||||||
});
|
|
||||||
|
|
||||||
item.addEventListener('mouseleave', (e) => {
|
// 防抖:延迟100ms再显示,避免频繁触发
|
||||||
isHovering = false;
|
hoverTimer = setTimeout(() => {
|
||||||
// 检查鼠标是否移到了下拉菜单上
|
// 关闭其他弹窗(搜索、语言、购买)
|
||||||
const relatedTarget = e.relatedTarget;
|
if (searchDropdown) searchDropdown.classList.remove('show');
|
||||||
const isMovingToDropdown = dropdown.contains(relatedTarget);
|
if (langDropdown) langDropdown.classList.remove('show');
|
||||||
|
if (buyDropdown) buyDropdown.classList.remove('show');
|
||||||
|
|
||||||
if (isMovingToDropdown) {
|
showDropdown(dropdown);
|
||||||
// 如果移向下拉菜单,不清除,等待下拉菜单的 mouseenter
|
// 打开蒙版层
|
||||||
return;
|
if (typeof openOverlay === 'function') openOverlay();
|
||||||
}
|
|
||||||
|
|
||||||
timer = setTimeout(() => {
|
|
||||||
if (!isHovering && !dropdown.matches(':hover')) {
|
|
||||||
hideDropdown();
|
|
||||||
}
|
|
||||||
}, 100);
|
}, 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', () => {
|
dropdown.addEventListener('mouseenter', () => {
|
||||||
isHovering = true;
|
if (leaveTimer) clearTimeout(leaveTimer);
|
||||||
clearTimeout(timer);
|
showDropdown(dropdown);
|
||||||
showDropdown();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
dropdown.addEventListener('mouseleave', (e) => {
|
// 鼠标移出下拉菜单
|
||||||
isHovering = false;
|
dropdown.addEventListener('mouseleave', () => {
|
||||||
// 检查鼠标是否移回了导航项
|
leaveTimer = setTimeout(() => {
|
||||||
const relatedTarget = e.relatedTarget;
|
const isHoveringNav = item.matches(':hover');
|
||||||
const isMovingToNavItem = item.contains(relatedTarget);
|
if (!isHoveringNav) {
|
||||||
|
hideDropdown(dropdown);
|
||||||
if (isMovingToNavItem) {
|
// 关闭蒙版层
|
||||||
return;
|
if (typeof closeOverlay === 'function') closeOverlay();
|
||||||
}
|
|
||||||
|
|
||||||
timer = setTimeout(() => {
|
|
||||||
if (!isHovering && !item.matches(':hover')) {
|
|
||||||
hideDropdown();
|
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 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 加载完成后执行)
|
// 初始化(在 DOM 加载完成后执行)
|
||||||
if (document.readyState === 'loading') {
|
if (document.readyState === 'loading') {
|
||||||
document.addEventListener('DOMContentLoaded', initHeaderDropdown);
|
document.addEventListener('DOMContentLoaded', initHeaderDropdown);
|
||||||
@@ -684,8 +750,8 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// // 初始化导航下拉菜单蒙版层
|
// 初始化导航下拉菜单蒙版层
|
||||||
// initNavDropdownOverlay();
|
initNavDropdownOverlay();
|
||||||
|
|
||||||
// 初始化渲染
|
// 初始化渲染
|
||||||
renderHistory();
|
renderHistory();
|
||||||
|
|||||||
@@ -97,11 +97,10 @@ a {
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 2px;
|
height: 0.125em;
|
||||||
background-color: #004bfa;
|
background-color: #004bfa;
|
||||||
transform: scaleX(0);
|
transform: scaleX(0);
|
||||||
transition: transform 0.2s ease;
|
transition: transform 0.2s ease;
|
||||||
z-index: 999;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-nav-title:hover::after,
|
.header-nav-title:hover::after,
|
||||||
@@ -148,7 +147,12 @@ a {
|
|||||||
transition: color 0.2s;
|
transition: color 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* .header-nav-btn img {
|
||||||
|
width: 1.5em;
|
||||||
|
max-width: 17px;
|
||||||
|
max-height: 17px;
|
||||||
|
height: 1.5em;
|
||||||
|
} */
|
||||||
|
|
||||||
.header-nav-btn:hover {
|
.header-nav-btn:hover {
|
||||||
color: #004bfa;
|
color: #004bfa;
|
||||||
@@ -265,7 +269,7 @@ a {
|
|||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
z-index: 99;
|
z-index: 999;
|
||||||
border-top: none;
|
border-top: none;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding-bottom: 2.375em;
|
padding-bottom: 2.375em;
|
||||||
@@ -335,7 +339,7 @@ a {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
max-width: 48%;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,7 +354,10 @@ a {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 单个分类区块 */
|
||||||
|
.header-category-block {
|
||||||
|
/* flex: 1; */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.header-category-title {
|
.header-category-title {
|
||||||
@@ -392,14 +399,13 @@ a {
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
font-size: 16px;
|
|
||||||
max-width: 748px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.header-product-card {
|
.header-product-card {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: calc(50% - 0.75em);
|
width: calc(50% - 0.75em);
|
||||||
max-width: 22.625em;
|
max-width: 22.625em;
|
||||||
flex-shrink: 1;
|
flex-shrink: 1;
|
||||||
@@ -423,12 +429,12 @@ a {
|
|||||||
transform: translateY(-2px)
|
transform: translateY(-2px)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* .header-product-card:nth-child(1) {
|
.header-product-card:nth-child(1) {
|
||||||
|
margin-right: 1.5em;
|
||||||
} */
|
}
|
||||||
|
|
||||||
.header-product-card:nth-child(3) {
|
.header-product-card:nth-child(3) {
|
||||||
|
margin-right: 1.5em;
|
||||||
margin-top: 1.5em;
|
margin-top: 1.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -436,7 +442,20 @@ a {
|
|||||||
margin-top: 1.5em;
|
margin-top: 1.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*.header-product-img {*/
|
||||||
|
/* width: 22.625em;*/
|
||||||
|
/* height: 12.25em;*/
|
||||||
|
/* background-color: #f5f5f5;*/
|
||||||
|
/* display: flex;*/
|
||||||
|
/* align-items: center;*/
|
||||||
|
/* justify-content: center;*/
|
||||||
|
/* color: #999;*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
/*.header-product-img img {*/
|
||||||
|
/* width: 22.625em;*/
|
||||||
|
/* height: 12.25em;*/
|
||||||
|
/*}*/
|
||||||
.header-product-img {
|
.header-product-img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
aspect-ratio: 22.625 / 12.25;
|
aspect-ratio: 22.625 / 12.25;
|
||||||
@@ -446,6 +465,7 @@ a {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
color: #999;
|
color: #999;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
/* border-radius: 0.5em; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-product-img img {
|
.header-product-img img {
|
||||||
|
|||||||
Reference in New Issue
Block a user