移动端菜单(通常称为“汉堡菜单”)的实现原理,核心在于CSS媒体查询与JavaScript类切换的协同工作。
首先,在HTML结构上,导航菜单被分为两个关键部分:一个用于触发操作的汉堡按钮(menu-toggle),以及一个包含所有导航链接的容器(nav-links)。
其次,在CSS中,系统通过@media (max-width: 768px)媒体查询来区分设备环境。在桌面端,导航链接默认横向排列展示,汉堡按钮则被隐藏;而在移动端,规则反转——汉堡按钮显示出来,导航链接容器默认被设置为display: none,从而在视觉上“收起”菜单。
实现“展开”与“收起”的关键,在于JavaScript的classList.toggle()方法。当用户点击汉堡按钮时,脚本会为导航链接容器动态添加或移除一个名为show的类。CSS中预先定义了.nav-links.show { display: flex; }这样的规则,因此当show类被添加时,原本隐藏的菜单就会以垂直列表的形式展开;当show类被移除时,菜单则重新隐藏。整个过程无需刷新页面,仅通过类名的状态切换即可实现流畅的交互效果。
<nav class="navbar">
<!-- Logo部分 -->
<a href="#" class="nav-logo">
<i class="fas fa-eye"></i>
<span>护眼中心</span>
</a>
<!-- 汉堡菜单按钮(默认隐藏,移动端显示) -->
<button class="menu-toggle" id="menuToggle" aria-label="菜单">
<i class="fas fa-bars"></i>
</button>
<!-- 导航链接列表 -->
<div class="nav-links" id="navLinks">
<a href="#" class="nav-link active">自我诊断</a>
<a href="#" class="nav-link">干眼科普</a>
<a href="#" class="nav-link">护眼产品</a>
<!-- 更多链接... -->
</div>
</nav>
/* 桌面端默认:汉堡按钮隐藏 */
.menu-toggle {
display: none;
}
/* 桌面端默认:导航链接横向排列 */
.nav-links {
display: flex;
align-items: center;
gap: 0.5rem;
flex-wrap: wrap;
}
/* 移动端(屏幕宽度 ≤ 768px):改变布局 */
@media (max-width: 768px) {
/* 显示汉堡按钮 */
.menu-toggle {
display: block;
}
/* 导航链接默认隐藏 */
.nav-links {
display: none;
width: 100%;
flex-direction: column;
gap: 0.3rem;
padding-top: 0.8rem;
}
/* 当有.show类时,显示导航链接 */
.nav-links.show {
display: flex;
}
/* 每个链接占满一行 */
.nav-link {
width: 100%;
justify-content: center;
padding: 0.7rem;
}
}
// 获取元素
const menuToggle = document.getElementById('menuToggle');
const navLinks = document.getElementById('navLinks');
// 点击汉堡按钮时,切换.show类
menuToggle.addEventListener('click', () => {
navLinks.classList.toggle('show');
// classList.toggle 的作用:
// - 如果navLinks没有show类 → 添加show类 → 菜单显示
// - 如果navLinks有show类 → 移除show类 → 菜单隐藏
});
// 点击导航链接后,自动关闭菜单(移动端体验优化)
navLinks.querySelectorAll('.nav-link').forEach(link => {
link.addEventListener('click', () => {
if (window.innerWidth <= 768) {
navLinks.classList.remove('show');
}
});
});
// 窗口大小改变时,重置菜单状态
window.addEventListener('resize', () => {
if (window.innerWidth > 768) {
navLinks.classList.remove('show');
}
});
.nav-links {
display: none;
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease;
}
.nav-links.show {
display: flex;
max-height: 500px; /* 足够大的值 */
}
这样菜单展开时就会有平滑的下拉动画效果。