汉堡菜单响应问题

Hamburger menu responsiveness issue

我正在尝试制作一个汉堡菜单,其中当使用超过 600px 的屏幕时,汉堡菜单以导航栏的形式显示,如果屏幕小于 600px,则显示为汉堡菜单。

我编写了代码,菜单按预期完美运行。然而,一旦菜单被切换然后关闭,并且屏幕尺寸增加,导航栏就会出现在它的位置之外。

这是网站加载的时间^

当使用汉堡包并增加屏幕尺寸时会发生这种情况。 另外,这是我第一次尝试汉堡菜单,我自己做的,如果可以的话,你能分享一些参考资料吗?

这里是HTML

<header>
        <h2>Hamburger Menu => </h2>
        <nav>
            <ul class="navbar">
                <li><a href="#">Home</a></li>
                <li><a href="#">Google</a></li>
                <li><a href="#">Youtube</a></li>
                <li><a href="#">Whosebug</a></li>
            </ul>
            <div class="cross"><i class="fas fa-times"></i></div>
            <div class="hamburger"><i class="fas fa-bars"></i></div>
        </nav>
    </header>

这里是CSS

*{
    margin: 0;
    padding: 0;
}

body{
    background: #ccc;
}

/* header */
header{
    width: 100%;
    min-height: 70px;
    display: flex;
    justify-content: space-between;
    background: #000033;
    color: #ff3300;
    align-items: center;
}

h2{
    margin: 0 0 0 1rem;
    text-shadow: 1px 1px 1px #ffad99;
}
/* navbar */
.navbar{
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    align-items: center;
    margin: 0 1rem 0 0;
}

/* links */
li{
    list-style: none;
}

a{
    color: #ff3300;
    text-decoration: none;
    text-shadow: 1px 1px 4px #ffad99;
    box-sizing: border-box;
}

a:hover{
    box-sizing: border-box;
    font-weight: bold;
    text-shadow: 1px 1px 1px #ffad99;
}

/* cross */
.cross{
    display: block;
    margin: 0 2rem 0 0;
    font-size: 1.5em;
    cursor: pointer;
}

.cross{
    display: none;
}

/* hamburger */
.hamburger{
    display: none;
}

/* media query for mobile */

@media(max-width:600px){
    .navbar{
        /* display: none; */
        position: absolute;
        width: 100vw;
        transform: translateX(-189%);
        top: 20vh;
        transition-duration: 2s;
        flex-direction: column;
        background: #000;
        height: 100vh;
        box-sizing: border-box;
    }

    li{
        margin: 0.4em 0.4rem ;
        padding: 0.9rem 5rem;
        border-bottom: 2px solid #fff;
        border-radius: 3px;
        box-sizing: border-box;
    }

    .hamburger{
        display: block;
        margin: 0 2rem 0 0;
        font-size: 1.5em;
        cursor: pointer;
    }
}

/* js classes */
.show{
    display: block;
}

.hide{
    display: none;
}

这里是 JAVASCRIPT

// * variables
const hamburger = document.querySelector('.hamburger');
const cross = document.querySelector('.cross');
const menu = document.querySelector('.navbar');

// functions
const showNav = () => {
    menu.style.transform = 'translateX(-89%)';
}

const hideNav = () => {
    menu.style.transform = 'translateX(-189%)'
}

// hamburger click event 
hamburger.addEventListener('click', () => {
    hamburger.classList.add('hide')
    hamburger.classList.remove('show')

    cross.classList.remove('hide')
    cross.classList.add('show')

    showNav();
});

cross.addEventListener('click', () => {
    cross.classList.remove('show')
    cross.classList.add('hide')

    hamburger.classList.remove('hide')

    hideNav();
});

所有答案将不胜感激。 我想再说一遍我的问题, 当使用汉堡菜单然后关闭时,如果屏幕大小调整为大于 @media 值,它会弄乱导航栏。我可以解决这个问题吗?

我的代码效率有点低 我是 javascript 的新手,所以非常感谢您提供基本语法的答案。

这是因为在 showNav() 中应用的转换仍然存在,所以 ul 元素在调用该函数后将始终向左移动。

解决这个问题的一种方法是在 @media 之后 .navbar:

中创建一个 .show-nav
@media (max-width: 600px) {

  .navbar {
    ...
  }

  .show-nav {
    transform: translateX(-89%);
  }

  ...

}

然后更新显示和隐藏功能以仅添加和删除 class:

const showNav = () => {
  menu.classList.add('show-nav')
}

const hideNav = () => {
  menu.classList.remove('show-nav')
}

这是一个包含建议更改的工作示例:

// * variables
const hamburger = document.querySelector('.hamburger')
const cross = document.querySelector('.cross')
const menu = document.querySelector('.navbar')

// functions
const showNav = () => {
  menu.classList.add('show-nav')
}

const hideNav = () => {
  menu.classList.remove('show-nav')
}

// hamburger click event
hamburger.addEventListener('click', () => {
  hamburger.classList.add('hide')
  hamburger.classList.remove('show')

  cross.classList.remove('hide')
  cross.classList.add('show')

  showNav()
})

cross.addEventListener('click', () => {
  cross.classList.remove('show')
  cross.classList.add('hide')

  hamburger.classList.remove('hide')

  hideNav()
})
* {
  margin: 0;
  padding: 0;
}

body {
  background: #ccc;
}


/* header */

header {
  width: 100%;
  min-height: 70px;
  display: flex;
  justify-content: space-between;
  background: #000033;
  color: #ff3300;
  align-items: center;
}

h2 {
  margin: 0 0 0 1rem;
  text-shadow: 1px 1px 1px #ffad99;
}


/* navbar */

.navbar {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  align-items: center;
  margin: 0 1rem 0 0;
}


/* links */

li {
  list-style: none;
}

a {
  color: #ff3300;
  text-decoration: none;
  text-shadow: 1px 1px 4px #ffad99;
  box-sizing: border-box;
}

a:hover {
  box-sizing: border-box;
  font-weight: bold;
  text-shadow: 1px 1px 1px #ffad99;
}


/* cross */

.cross {
  display: block;
  margin: 0 2rem 0 0;
  font-size: 1.5em;
  cursor: pointer;
}

.cross {
  display: none;
}


/* hamburger */

.hamburger {
  display: none;
}


/* media query for mobile */

@media (max-width: 600px) {
  .navbar {
    /* display: none; */
    position: absolute;
    width: 100vw;
    transform: translateX(-189%);
    top: 20vh;
    transition-duration: 2s;
    flex-direction: column;
    background: #000;
    height: 100vh;
    box-sizing: border-box;
  }
  .show-nav {
    transform: translateX(-89%);
  }
  li {
    margin: 0.4em 0.4rem;
    padding: 0.9rem 5rem;
    border-bottom: 2px solid #fff;
    border-radius: 3px;
    box-sizing: border-box;
  }
  .hamburger {
    display: block;
    margin: 0 2rem 0 0;
    font-size: 1.5em;
    cursor: pointer;
  }
  /* js classes */
  .show {
    display: block;
  }
  .hide {
    display: none;
  }
}
<header>
  <h2>Hamburger Menu =></h2>
  <nav>
    <ul class="navbar">
      <li><a href="#">Home</a></li>
      <li><a href="#">Google</a></li>
      <li><a href="#">Youtube</a></li>
      <li><a href="#">Whosebug</a></li>
    </ul>
    <div class="cross"><i class="fas fa-times"></i>X</div>
    <div class="hamburger"><i class="fas fa-bars"></i>|||</div>
  </nav>
</header>