0

0

使用原生 JavaScript 实现响应式多级下拉菜单(悬停与点击切换)

DDD

DDD

发布时间:2025-09-09 18:37:43

|

568人浏览过

|

来源于php中文网

原创

使用原生 javascript 实现响应式多级下拉菜单(悬停与点击切换)

本文旨在指导开发者使用原生 JavaScript、HTML 和 CSS 构建一个响应式的多级下拉菜单。该菜单在桌面端通过鼠标悬停展开,在移动端则通过点击展开。文章将详细介绍实现思路、代码示例以及注意事项,帮助读者理解并掌握如何在不同设备上提供最佳的用户体验。

HTML 结构

首先,我们需要构建 HTML 结构。一个典型的多级下拉菜单包含一个 div 容器,内部包含一个无序列表 ul,列表项 li 可能包含嵌套的 ul 列表,形成多级菜单。

建议使用 标签包裹菜单项文本,以便添加链接。对于顶级 li 标签,可以考虑使用 标签包裹文本,方便样式控制和语义化。例如:

  • Link
    • Child Link
    • Child Link
  • CSS 样式

    CSS 负责菜单的布局和外观。关键点在于如何实现悬停效果和媒体查询,以便在不同屏幕尺寸下应用不同的样式。

    .menu {
      --menu-height: 40px;
      box-sizing: border-box;
      position: fixed;
      top: 0;
      left: 0;
      width: 100vw;
    }
    .menu ul {
      list-style: none;
      padding: 16px;
      margin: 0;
    }
    .menu ul li,
    .menu ul li a {
      opacity: 0.8;
      color: #ffffff;
      cursor: pointer;
      transition: 200ms;
      text-decoration: none;
      white-space: nowrap;
      font-weight: 700;
    }
    .menu ul li a,
    .menu ul li a a {
      display: flex;
      align-items: center;
      height: 100%;
      width: 100%;
    }
    .menu ul li {
      padding-right: 36px;
    }
    .menu ul li::before {
      content: "";
      width: 0;
      height: 0;
      border-left: 5px solid transparent;
      border-right: 5px solid transparent;
      border-top: 5px solid #ffa500;
      position: absolute;
      right: 8px;
      top: 50%;
      transform: translateY(-50%);
    }
    .menu ul .link::before {
      padding-right: 0;
      display: none;
    }
    .menu > ul {
      display: flex;
      height: var(--menu-height);
      align-items: center;
      background-color: #000000;
    }
    .menu > ul li {
      position: relative;
      margin: 0 8px;
    }
    .menu > ul li ul {
      visibility: hidden;
      opacity: 0;
      padding: 0;
      min-width: 160px;
      background-color: #333;
      position: absolute;
      top: 45px;
      left: 50%;
      transform: translateX(-50%);
      transition: 200ms;
      transition-delay: 200ms;
    }
    .menu > ul li ul li {
      margin: 0;
      padding: 8px 16px;
      display: flex;
      align-items: center;
      justify-content: flex-start;
      height: 30px;
      padding-right: 40px;
    }
    .menu > ul li ul li::before {
      width: 0;
      height: 0;
      border-top: 5px solid transparent;
      border-bottom: 5px solid transparent;
      border-left: 5px solid #ffa500;
    }
    .menu > ul li ul li ul {
      top: -2%;
      left: 100%;
      transform: translate(0);
    }
    
    .show {
      display: flex;
    }
    
    .hide {
      display: none;
    }
    
    @media screen and (min-width: 1200px) {
      .menu ul li:hover,
      .menu ul li a:hover {
        opacity: 1;
      }
      .menu > ul li ul li:hover {
        background: black;
      }
      .menu > ul li:hover > ul {
        opacity: 1;
        visibility: visible;
        transition-delay: 0ms;
      }
    }
    
    @media screen and (max-width: 1200px) {
      .menu {
        height: 100vh;
        top: 0;
        left: 0;
        width: 20vw;
      }
      .menu ul {
        flex-direction: column;
        height: 100vh;
      }
      .menu ul li {
        margin: 1rem 0;
      }
      .menu ul li ul {
        visibility: hidden;
        opacity: 0;
        padding: 0;
        min-width: 160px;
        background-color: #333;
        position: absolute;
        top: 0px;
        left: 200%;
        transform: translateX(-50%);
        transition: 200ms;
        transition-delay: 200ms;
        height: fit-content;
      }
    }
    
    .menu ul.show { /* 关键代码 */
        visibility: visible;
        opacity: 1;
    }

    关键点:

    立即学习Java免费学习笔记(深入)”;

    • 隐藏子菜单: 默认情况下,使用 visibility: hidden; 和 opacity: 0; 隐藏子菜单。
    • 悬停效果: 在桌面端媒体查询中,使用 :hover 伪类来改变子菜单的 visibility 和 opacity,实现悬停展开效果。
    • 移动端样式: 在移动端媒体查询中,可以调整菜单的布局,例如将其设置为垂直排列
    • .menu ul.show: 这个CSS规则是解决问题的关键。它确保当 show 类被添加到 ul 元素时,该元素的 visibility 和 opacity 属性被正确设置,从而显示子菜单。

    JavaScript 交互

    JavaScript 用于处理移动端的点击事件,实现点击展开/收起子菜单的功能。

    GitHub Copilot
    GitHub Copilot

    GitHub AI编程工具,实时编程建议

    下载
    let menu = document.querySelector(".menu ul");
    menu = menu.children;
    
    for (let i = 0; i < menu.length; i++) {
      console.log(menu[i]);
      menu[i].addEventListener("click", function() {
        menu[i].firstElementChild.classList.toggle("show");
        console.log(menu[i].firstElementChild);
      });
    }

    这段代码遍历顶级菜单项,并为每个菜单项添加点击事件监听器。当点击菜单项时,它会切换其第一个子元素(通常是子菜单 ul)的 show 类。

    改进建议:

    1. 更精确的选择器: 使用更精确的选择器来避免潜在的问题。例如,可以使用 document.querySelectorAll(".menu > ul > li") 来选择顶级菜单项。
    2. 事件委托: 使用事件委托可以提高性能,尤其是在菜单项数量较多时。将事件监听器添加到父元素(例如 .menu ul),然后根据点击的目标元素来判断是否需要展开/收起子菜单。
    3. 判断屏幕尺寸: 在 JavaScript 中判断当前屏幕尺寸,只在移动端应用点击事件处理程序,避免与桌面端的悬停效果冲突。可以使用 window.innerWidth 或 window.matchMedia 来判断屏幕尺寸。

    示例代码(包含改进):

    document.addEventListener('DOMContentLoaded', function() {
        const menu = document.querySelector('.menu ul');
    
        // 仅在移动设备上启用点击事件
        if (window.innerWidth <= 1200) { // 假设1200px是移动端和桌面端的分割点
            menu.addEventListener('click', function(event) {
                const target = event.target;
    
                // 检查点击的是否是顶级菜单项
                if (target.tagName === 'LI' && target.parentElement === menu) {
                    const subMenu = target.querySelector('ul'); // 查找子菜单
    
                    if (subMenu) {
                        event.preventDefault(); // 阻止默认行为(例如,如果菜单项是链接)
                        subMenu.classList.toggle('show'); // 切换 show 类
                    }
                }
            });
        }
    });

    代码解释:

    • document.addEventListener('DOMContentLoaded', function() { ... });:确保在DOM加载完成后执行JavaScript代码。
    • window.innerWidth
    • target.tagName === 'LI' && target.parentElement === menu:检查点击的元素是否是顶级菜单项。
    • target.querySelector('ul'):查找当前菜单项的子菜单。
    • event.preventDefault():阻止默认行为,例如,如果菜单项是一个链接,阻止页面跳转。
    • subMenu.classList.toggle('show'):切换子菜单的 show 类,从而显示或隐藏子菜单。

    总结

    通过 HTML 构建菜单结构,CSS 控制菜单样式和响应式布局,JavaScript 处理移动端的点击交互,我们可以实现一个功能完善、用户体验良好的响应式多级下拉菜单。记住,清晰的结构、合理的样式和简洁的 JavaScript 代码是构建高质量 Web 应用的关键。根据实际需求,你可以进一步优化代码,例如添加动画效果、自定义样式等。

    热门AI工具

    更多
    DeepSeek
    DeepSeek

    幻方量化公司旗下的开源大模型平台

    豆包大模型
    豆包大模型

    字节跳动自主研发的一系列大型语言模型

    通义千问
    通义千问

    阿里巴巴推出的全能AI助手

    腾讯元宝
    腾讯元宝

    腾讯混元平台推出的AI助手

    文心一言
    文心一言

    文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

    讯飞写作
    讯飞写作

    基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

    即梦AI
    即梦AI

    一站式AI创作平台,免费AI图片和视频生成。

    ChatGPT
    ChatGPT

    最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

    相关专题

    更多
    function是什么
    function是什么

    function是函数的意思,是一段具有特定功能的可重复使用的代码块,是程序的基本组成单元之一,可以接受输入参数,执行特定的操作,并返回结果。本专题为大家提供function是什么的相关的文章、下载、课程内容,供大家免费下载体验。

    482

    2023.08.04

    js函数function用法
    js函数function用法

    js函数function用法有:1、声明函数;2、调用函数;3、函数参数;4、函数返回值;5、匿名函数;6、函数作为参数;7、函数作用域;8、递归函数。本专题提供js函数function用法的相关文章内容,大家可以免费阅读。

    163

    2023.10.07

    DOM是什么意思
    DOM是什么意思

    dom的英文全称是documentobjectmodel,表示文件对象模型,是w3c组织推荐的处理可扩展置标语言的标准编程接口;dom是html文档的内存中对象表示,它提供了使用javascript与网页交互的方式。想了解更多的相关内容,可以阅读本专题下面的文章。

    3299

    2024.08.14

    li是什么元素
    li是什么元素

    li是HTML标记语言中的一个元素,用于创建列表。li代表列表项,它是ul或ol的子元素,li标签的作用是定义列表中的每个项目。本专题为大家li元素相关的各种文章、以及下载和课程。

    419

    2023.08.03

    Python 自然语言处理(NLP)基础与实战
    Python 自然语言处理(NLP)基础与实战

    本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

    10

    2026.01.27

    拼多多赚钱的5种方法 拼多多赚钱的5种方法
    拼多多赚钱的5种方法 拼多多赚钱的5种方法

    在拼多多上赚钱主要可以通过无货源模式一件代发、精细化运营特色店铺、参与官方高流量活动、利用拼团机制社交裂变,以及成为多多进宝推广员这5种方法实现。核心策略在于通过低成本、高效率的供应链管理与营销,利用平台社交电商红利实现盈利。

    109

    2026.01.26

    edge浏览器怎样设置主页 edge浏览器自定义设置教程
    edge浏览器怎样设置主页 edge浏览器自定义设置教程

    在Edge浏览器中设置主页,请依次点击右上角“...”图标 > 设置 > 开始、主页和新建标签页。在“Microsoft Edge 启动时”选择“打开以下页面”,点击“添加新页面”并输入网址。若要使用主页按钮,需在“外观”设置中开启“显示主页按钮”并设定网址。

    16

    2026.01.26

    苹果官方查询网站 苹果手机正品激活查询入口
    苹果官方查询网站 苹果手机正品激活查询入口

    苹果官方查询网站主要通过 checkcoverage.apple.com/cn/zh/ 进行,可用于查询序列号(SN)对应的保修状态、激活日期及技术支持服务。此外,查找丢失设备请使用 iCloud.com/find,购买信息与物流可访问 Apple (中国大陆) 订单状态页面。

    131

    2026.01.26

    npd人格什么意思 npd人格有什么特征
    npd人格什么意思 npd人格有什么特征

    NPD(Narcissistic Personality Disorder)即自恋型人格障碍,是一种心理健康问题,特点是极度夸大自我重要性、需要过度赞美与关注,同时极度缺乏共情能力,背后常掩藏着低自尊和不安全感,影响人际关系、工作和生活,通常在青少年时期开始显现,需由专业人士诊断。

    7

    2026.01.26

    热门下载

    更多
    网站特效
    /
    网站源码
    /
    网站素材
    /
    前端模板

    精品课程

    更多
    相关推荐
    /
    热门推荐
    /
    最新课程
    Sass 教程
    Sass 教程

    共14课时 | 0.8万人学习

    Bootstrap 5教程
    Bootstrap 5教程

    共46课时 | 3万人学习

    CSS教程
    CSS教程

    共754课时 | 24.3万人学习

    关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号 技术交流群
    PHP中文网订阅号
    每天精选资源文章推送

    Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号