移动端菜单的实现原理

📅 发布时间:2026-08-14 👁️ 阅读次数:1007 次

移动端菜单(通常称为“汉堡菜单”)的实现原理,核心在于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类被移除时,菜单则重新隐藏。整个过程无需刷新页面,仅通过类名的状态切换即可实现流畅的交互效果。

1、HTML 结构

<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>

2、CSS 样式(关键部分)

/* 桌面端默认:汉堡按钮隐藏 */
.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;
    }
}

3、JavaScript 交互逻辑

// 获取元素
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');
    }
});

如果您想要添加动画效果,可以进一步修改CSS:

.nav-links {
    display: none;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.3s ease;
}

.nav-links.show {
    display: flex;
    max-height: 500px; /* 足够大的值 */
}

这样菜单展开时就会有平滑的下拉动画效果。