【问题标题】:Addressing issue with disappearing li elements in navbar (HTML, CSS, JS)解决导航栏中 li 元素消失的问题(HTML、CSS、JS)
【发布时间】:2021-04-27 19:07:58
【问题描述】:

document.addEventListener("DOMContentLoaded", () => {
  let menuBtn = document.querySelector("#menu-button");
  let menu = document.querySelector("#menu");
  let menuItems = menu.getElementsByTagName("li");

  menuBtn.addEventListener("click", e => {
    if (e.target.innerText === ("✕")) {
      e.target.innerText = "☰";
      [...menuItems].forEach(item => item.style.display = "none");
    } else if (e.target.innerText === "☰") {
      e.target.innerText = "✕";
      [...menuItems].forEach(item => item.style.display = "block");
    }
  });
});
  header {
  width: 100%;
  height: 100px;
}

#menu {
  display: flex;
  flex-direction: row;
  margin: 0 auto;
  justify-content: space-around;
  font-size: 2rem;
}

#menu-button {
  display: none;
}

li {
  list-style-type: none;
}

a {
  text-decoration: none;
  color: rgb(0, 0, 0);
}

@media screen and (max-width: 1050px) {
  #menu {
    flex-direction: column;
    width: 100%;
    height: 100%;
  }
  #menu li {
    padding: 1.5rem;
    display: none;
  }
  #menu-button {
    display: block;
    font-size: 3rem;
    cursor: pointer;
    outline: none;
    border: none;
  }
}
<header>
  <nav>
    <button id="menu-button">☰</button>
    <ul id="menu">
      <li><a href="#">Home</a></li>
      <li><a href="#">About</a></li>
      <li><a href="#">Contact</a></li>
    </ul>
  </nav>
</header>

这是一个简单的导航菜单,采用桌面优先方法,使用flexbox

  1. 视口小于 1050 像素,因此显示汉堡按钮
  2. 单击汉堡按钮以下拉形式显示菜单。汉堡按钮变为“X”。
  3. “X”被点击。 JS 代码将所有li 元素更改为display: none
  4. 问题:视口增加到超过 1050 像素的断点。由于li 元素已更改为display: none,因此未显示菜单。

不胜感激有关如何解决此问题的建议。

还有,小而烦人的问题。

  1. 视口小于 1050 像素,因此显示汉堡按钮
  2. 单击汉堡按钮以下拉形式显示菜单。汉堡按钮变为“X”。
  3. 视口增加到超过 1050p 的断点,然后回到断点以下。由于所有li 元素在JS 代码中都设置为display: block,因此会出现下拉菜单。我想让它在视口大小减小时出现汉堡图标。

感谢大家的帮助!

【问题讨论】:

    标签: javascript html css navbar


    【解决方案1】:

    添加和删除 CSS 类,而不是设置内联样式。这样做会给 CSS 更多的控制权。内联样式只能使用 !important 覆盖,这将使其更难覆盖。

    不显示和隐藏每个&lt;li&gt;,只隐藏父&lt;ul&gt;。这也将隐藏其中的所有孩子。

    下面的示例在单击菜单按钮时向#menu 元素添加和删除active 类。这个活动类在移动设备上显示#menu 隐藏的位置。在较大的屏幕上,始终显示#menu

    document.addEventListener("DOMContentLoaded", () => {
      let menuBtn = document.querySelector("#menu-button");
      let menu = document.querySelector("#menu");
    
      // First question: 
      // Add a class instead of inline styles.
      menuBtn.addEventListener("click", e => {
        if (e.target.innerText === ("✕")) {
          e.target.innerText = "☰";
          menu.classList.remove('active');
        } else if (e.target.innerText === "☰") {
          e.target.innerText = "✕";
          menu.classList.add('active');
        }
      });
      
      // Second question:
      // Watch a media query, reset the button and hide the 
      // menu when changing from large to a small size.
      const mediaQuery = window.matchMedia('screen and (max-width: 1050px)');
      mediaQuery.addEventListener('change', ({ matches }) => {
        if (!matches) return;
        menuBtn.innerText = "☰";
        menu.classList.remove('active');
      });
    });
    header {
      width: 100%;
      height: 100px;
    }
    
    #menu {
      display: flex;
      flex-direction: row;
      margin: 0 auto;
      justify-content: space-around;
      font-size: 2rem;
    }
    
    #menu-button {
      display: none;
    }
    
    li {
      list-style-type: none;
    }
    
    a {
      text-decoration: none;
      color: rgb(0, 0, 0);
    }
    
    @media screen and (max-width: 1050px) {
      #menu {
        display: none;
        flex-direction: column;
        width: 100%;
        height: 100%;
      }
      
      #menu.active {
        display: flex;
      }
    
      #menu li {
        padding: 1.5rem;
      }
      
      #menu-button {
        display: block;
        font-size: 3rem;
        cursor: pointer;
        outline: none;
        border: none;
      }
    <header>
      <nav>
        <button id="menu-button">☰</button>
        <ul id="menu">
          <li><a href="#">Home</a></li>
          <li><a href="#">About</a></li>
          <li><a href="#">Contact</a></li>
        </ul>
      </nav>
    </header>

    【讨论】:

    • 感谢您非常有帮助的回复!我正努力有意识地尽可能多地使用类而不是内联代码,但我认为好处只是更清洁、更易读、更易于维护的代码。我什至不知道!important。关于解决我的第二个问题的任何想法?再次感谢。
    • 不客气。我不确定我是否理解第二个问题。你能详细说明一下吗?
    • 如果您单击汉堡按钮使菜单元素以垂直布局显示,然后增加视口大小,您会看到菜单元素以水平布局显示。没关系。现在,如果您减小视口大小,菜单元素将出现在垂直布局中。我希望显示汉堡按钮而不是菜单元素。换句话说,任何时候我们点击媒体查询断点小于 1050 像素,我希望汉堡按钮默认显示。这有意义吗?
    • 我明白了。我已经修改了答案。添加的是window.matchMedia 的用法,它返回MediaQueryList。每当媒体查询是否匹配时,此列表都会触发一个事件。所以当它匹配时,它会重置按钮并隐藏菜单。
    • 非常感谢。如果没有你的帮助,我不会想到我应该使用MediaQueryList
    猜你喜欢
    • 2022-10-01
    • 2020-12-21
    • 2015-09-15
    • 2017-11-12
    • 2018-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多