【问题标题】:Hamburger Menu Toggle汉堡 菜单切换
【发布时间】:2021-12-16 19:08:35
【问题描述】:

我正在为摄影网站创建登录页面,但我遇到了汉堡菜单问题。

桌面视图 - 导航栏正常工作。当我切换到移动视图时,汉堡菜单只显示第一个列表项。我使用 HTML、CSS 和 JS 来创建它。

它似乎只显示第一个列表项。我确定我遗漏了一些简单的东西,但找不到!

任何帮助将不胜感激!

const hamburger =  document.getElementById('hamburger');
const navItem =  document.getElementById('nav-item');

hamburger.addEventListener('click', () => {
  navItem.classList.toggle('show');
});
.hamburger {
  cursor: pointer;
  padding-left: 1rem;
}

.nav-item {
  display: none;
}

.nav-item.show {
  display: flex;
  flex-direction: column;
  align-items: center;
}

ul {
  background-color: var(--Dark-blue);
  padding-top: 1rem;
  padding-bottom: 1rem;
}

@media (min-width: 750px) {
  .hamburger {
    display: none;
  }

  .nav-list {
    display: flex;
    justify-content: right;
  }

  .nav-item {
    display: block;
  }
}
<ul class="nav-list" id="nav-list">
        <img
          class="hamburger"
          id="hamburger"
          src="icon-hamburger.svg"
          alt=""
          aria-hidden="true"
        />

        <li id="nav-item" class="nav-item"><a href="#">Home</a></li>
        <li id="nav-item" class="nav-item"><a href="#">Highlights</a></li>
        <li id="nav-item" class="nav-item"><a href="#">Portfolio</a></li>
        <li id="nav-item" class="nav-item"><a href="#">Bio</a></li>
        <li id="nav-item" class="nav-item"><a href="#">Blog</a></li>
        <li id="nav-item" class="nav-item"><a href="#">Contact</a></li>
</ul>

【问题讨论】:

    标签: javascript html css hamburger-menu


    【解决方案1】:

    当您使用getElementById 时,它只会返回第一个匹配项。 ID 预计每次使用都是唯一的,因此为什么您只会在代码中获得第一个 li 元素是有道理的。虽然我不明白为什么您在定义类的同时使用 id 进行查询选择(与 id 相比,它用于影响 至少 一个元素),但它是您应该使用的。

    顺便说一句,您应该为相同类型的元素使用类,例如 li 项目,而不是将其添加到 ul 标记中。如果是用于样式的事件,您添加到列表元素的样式也将添加到您的 ul 元素中。

    所以这里是一个例子:

    <ul class="nav-list" id="nav-list">
      <img id="hamburger" src="icon-hamburger.svg" alt="HAMBURGER" aria-hidden="true" />
    
      <li class="nav-item"><a href="#">Home</a></li>
      <li class="nav-item"><a href="#">Highlights</a></li>
      <li class="nav-item"><a href="#">Portfolio</a></li>
      <li class="nav-item"><a href="#">Bio</a></li>
      <li class="nav-item"><a href="#">Blog</a></li>
      <li class="nav-item"><a href="#">Contact</a></li>
    </ul>
    
    const hamburger =  document.getElementById('hamburger');
    const navItems =  Array.from(document.querySelectorAll('.nav-item'));
    
     hamburger.addEventListener('click', () => {
       console.log(navItems); // you can see your nav items in console everytime you click the button
       navItems.forEach(navItem => navItem.classList.toggle('show'))
     });
    

    CSS 是一样的。

    旁注: George Sun 的回答是你应该做的。我的回答更多的是关于你应该如何使用 ids/classes 并收集多个元素。

    【讨论】:

    • 您好 Alk,感谢您的帮助。我只编码了 3 个月(ish),并且仍在尝试学习最佳实践。我会记住这一点的! ID 一次性使用,类多次使用
    【解决方案2】:

    id 属性的每个值只能在文档中使用一次。因此,您的document.getElementById('nav-item') 只是寻找具有id 属性nav-item 的第一个元素并对其进行操作。为了显示您的所有列表项,我改为将id="nav-item" 应用到span,父母都是li,并从列表项中删除了id。这将允许在单击菜单图标时显示所有列表项,并且不依赖于所有应用了正确类的列表项。我也相应地更新了你的 CSS。

    为了便于说明,我还将您的图片引用替换为 Stack Overflow 徽标,因为您的代码 sn-p 引用了本地文件。

    const hamburger =  document.getElementById('hamburger');
    const navItem =  document.getElementById('nav-item');
    
    hamburger.addEventListener('click', () => {
      navItem.classList.toggle('show');
    });
    .hamburger {
      cursor: pointer;
      padding-left: 1rem;
    }
    
    #nav-item li { /* updated */
      display: none;
    }
    
    #nav-item.show li { /* updated */
      display: flex;
      flex-direction: column;
      align-items: center;
    }
    
    ul {
      background-color: var(--Dark-blue);
      padding-top: 1rem;
      padding-bottom: 1rem;
    }
    
    @media (min-width: 750px) {
      .hamburger {
        display: none;
      }
    
      .nav-list {
        display: flex;
        justify-content: right;
      }
    
      .nav-item {
        display: block;
      }
    }
    <ul class="nav-list" id="nav-list">
            <img
              class="hamburger"
              id="hamburger"
              src="https://stackoverflow.design/assets/img/logos/so/logo-stackoverflow.svg"
              alt=""
              aria-hidden="true"
            />
    
        <span id="nav-item">
            <li class="nav-item"><a href="#">Home</a></li>
            <li class="nav-item"><a href="#">Highlights</a></li>
            <li class="nav-item"><a href="#">Portfolio</a></li>
            <li class="nav-item"><a href="#">Bio</a></li>
            <li class="nav-item"><a href="#">Blog</a></li>
            <li class="nav-item"><a href="#">Contact</a></li>
        </span>
    </ul>

    【讨论】:

    • 谢谢你,乔治孙!我只写了几个月的代码,仍在努力学习最佳实践。为您的所有帮助干杯!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-10
    • 1970-01-01
    • 1970-01-01
    • 2018-05-18
    • 1970-01-01
    相关资源
    最近更新 更多