You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

餐厅菜单点击展开功能优化:寻求简洁实现方案

Hey there! 我懂你现在用重复类名关联菜单分区标题和菜品列表的方式有多麻烦——既要维护一堆重复的类,代码看起来也不够清爽。其实我们有几个更简洁优雅的方案,完全不用依赖重复类名来实现交互:

方案1:利用HTML5 data-* 属性关联元素

这种方式让标题和对应菜品区域的关联关系一目了然,后期维护也更方便:

修改后的HTML结构

<div class="menu-group">
  <h2 class="section-header" data-target="appetizers">开胃菜</h2>
  <div id="appetizers" class="entry" hidden>
    <div class="dish">凉拌黄瓜</div>
    <div class="dish">盐水花生</div>
  </div>
</div>

<div class="menu-group">
  <h2 class="section-header" data-target="main-courses">主菜</h2>
  <div id="main-courses" class="entry" hidden>
    <div class="dish">红烧肉</div>
    <div class="dish">清蒸鱼</div>
  </div>
</div>

对应的JavaScript代码

// 给所有分区标题绑定点击事件
document.querySelectorAll('.section-header').forEach(header => {
  header.addEventListener('click', () => {
    // 通过data-target属性获取目标菜品区域的ID
    const targetId = header.dataset.target;
    const targetSection = document.getElementById(targetId);
    // 切换显示/隐藏状态
    targetSection.hidden = !targetSection.hidden;
  });
});

方案2:依托DOM层级关系自动匹配

如果你的菜单结构是规整的(每个标题和对应菜品区域在同一个父容器里),完全不需要额外属性,直接通过DOM层级查找即可:

规整的HTML结构

<div class="menu-group">
  <h2 class="section-header">开胃菜</h2>
  <div class="entry" hidden>
    <div class="dish">凉拌黄瓜</div>
    <div class="dish">盐水花生</div>
  </div>
</div>

<div class="menu-group">
  <h2 class="section-header">主菜</h2>
  <div class="entry" hidden>
    <div class="dish">红烧肉</div>
    <div class="dish">清蒸鱼</div>
  </div>
</div>

对应的JavaScript代码

document.querySelectorAll('.section-header').forEach(header => {
  header.addEventListener('click', () => {
    // 直接查找当前标题的下一个兄弟元素(就是对应的菜品区域)
    const targetEntry = header.nextElementSibling;
    // 或者如果结构有变化,也可以通过父容器查找:
    // const targetEntry = header.parentElement.querySelector('.entry');
    targetEntry.hidden = !targetEntry.hidden;
  });
});

进阶优化:用CSS类控制显示状态

如果需要更灵活的样式控制(比如过渡动画),建议用CSS类代替直接操作hidden属性或行内样式:

新增CSS类

.entry.hidden {
  display: none;
  /* 可以加过渡效果,比如:
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease;
  */
}

修改后的JavaScript代码

document.querySelectorAll('.section-header').forEach(header => {
  header.addEventListener('click', () => {
    const targetEntry = header.nextElementSibling;
    // 切换hidden类
    targetEntry.classList.toggle('hidden');
  });
});

如果需要实现手风琴效果(点击一个区域关闭其他所有区域),只需要在点击时先隐藏所有菜品区域,再切换当前目标:

document.querySelectorAll('.section-header').forEach(header => {
  header.addEventListener('click', () => {
    const targetEntry = header.nextElementSibling;
    // 隐藏所有非当前目标的菜品区域
    document.querySelectorAll('.entry').forEach(entry => {
      if (entry !== targetEntry) {
        entry.classList.add('hidden');
      }
    });
    // 切换当前目标的状态
    targetEntry.classList.toggle('hidden');
  });
});

内容的提问来源于stack exchange,提问作者Justin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:39:29