Переключение значка меню

#javascript #html #css

Вопрос:

Я пытаюсь отключить значок меню при нажатии и нажать на значок «x». Точно так же мне нужно, чтобы произошло обратное. При нажатии на значок » x » выключается, а значок меню снова включается.

При nav-button-menuOpen нажатии три divs кнопки внутри переходят от opacity: 1; к opacity: 0; , и кнопка исчезает, как и должно быть. Тогда span внутренняя nav-button-menuClose часть должна идти от opacity: 0; до opacity: 1; . Я вижу, что класс добавляется в браузере, но анимация на span нем не изменяет свойство непрозрачности.

 const mobileMenuOpenAndClose = () => {
    const menuOpenButton = document.querySelector('.nav-button-menuOpen');
    const menuCloseButton= document.querySelector('.nav-button-menuClose');
    const navMobileMenu = document.querySelector('.nav-mobileMenu');
    const navMobileMenuLinks = document.querySelectorAll('.nav-mobileMenu-links');

    menuOpenButton.addEventListener('click', () => {
      console.log('menuButtonOpen clicked');
      menuOpenButton.classList.toggle('nav-button-toggle');
      menuCloseButton.classList.toggle('nav-button-toggle');
    });

    menuCloseButton.addEventListener('click', () => {
      console.log('menuButtonClose clicked')
      menuCloseButton.classList.toggle('nav-button-toggle');
      menuOpenButton.classList.toggle('nav-button-toggle');
    });
};

mobileMenuOpenAndClose(); 
 /* Hamburger Menu */
nav .nav-button-menuOpen {
  justify-self: end;
  cursor: pointer;
  display: inline-block;
  opacity: 1;
}
nav .nav-button-menuOpen div {
  width: 30px;
  height: 30px;
  height: 3px;
  margin: 5px 0;
  background-color: var(--color-black);
  transition: all;
}
nav .nav-button-menuClose {
  justify-self: end;
  cursor: pointer;
  display: inline-block;
  opacity: 0;
}
nav .nav-button-menuClose span {
  color: var(--color-black);
  font-size: 1rem;
  transition: all;
}
nav .nav-button-toggle .menuOpen-line  {
  opacity: 0;
}
nav .nav-button-toggle .nav-button-menuClose { 
    opacity: 1; 
}  
 <nav>
<div class="nav-button-menuOpen">
  <div class="menuOpen-line"></div>
  <div class="menuOpen-line"></div>
  <div class="menuOpen-line"></div>
</div>
<div class="nav-button-menuClose">
  <span>x</span>
</div>
</nav> 

Ответ №1:

Написание css с пробелом посередине выглядит следующим образом: .nav-button-toggle .nav-button-menuClose примените стиль к дочерним элементам. Пишите .nav-button-toggle.nav-button-menuClose без пробела посередине, чтобы применить его к себе.

 const mobileMenuOpenAndClose = () => {
    const menuOpenButton = document.querySelector('.nav-button-menuOpen');
    const menuCloseButton= document.querySelector('.nav-button-menuClose');
    const navMobileMenu = document.querySelector('.nav-mobileMenu');
    const navMobileMenuLinks = document.querySelectorAll('.nav-mobileMenu-links');

    menuOpenButton.addEventListener('click', () => {
      console.log('menuButtonOpen clicked');
      menuOpenButton.classList.toggle('nav-button-toggle');
      menuCloseButton.classList.toggle('nav-button-toggle');
    });

    menuCloseButton.addEventListener('click', () => {
      console.log('menuButtonClose clicked')
      menuCloseButton.classList.toggle('nav-button-toggle');
      menuOpenButton.classList.toggle('nav-button-toggle');
    });
};

mobileMenuOpenAndClose(); 
 /* Hamburger Menu */
nav .nav-button-menuOpen {
  justify-self: end;
  cursor: pointer;
  display: inline-block;
  opacity: 1;
}
nav .nav-button-menuOpen div {
  width: 30px;
  height: 30px;
  height: 3px;
  margin: 5px 0;
  background-color: black;
  transition: all;
}
nav .nav-button-menuClose {
  justify-self: end;
  cursor: pointer;
  display: inline-block;
  opacity: 0;
}
nav .nav-button-menuClose span {
  color: black;
  font-size: 1rem;
  transition: all;
}
nav .nav-button-toggle .menuOpen-line  {
  opacity: 0;
}
nav .nav-button-toggle.nav-button-menuClose { 
    opacity: 1; 
} 
 <nav>
<div class="nav-button-menuOpen">
  <div class="menuOpen-line"></div>
  <div class="menuOpen-line"></div>
  <div class="menuOpen-line"></div>
</div>
<div class="nav-button-menuClose">
  <span>x</span>
</div>
</nav> 

Для части анимации я бы рекомендовал вам использовать правило CSS @keyframes (https://www.w3schools.com/cssref/css3_pr_animation-keyframes.asp) вместо transiton . Таким образом, вы можете легко применить класс скрытия display: none; к скрытым элементам, и если вы удалите класс, анимация запустится.

 const mobileMenuOpenAndClose = () => {
    const menuOpenButton = document.querySelector('.nav-button-menuOpen');
    const menuCloseButton= document.querySelector('.nav-button-menuClose');
    const navMobileMenu = document.querySelector('.nav-mobileMenu');
    const navMobileMenuLinks = document.querySelectorAll('.nav-mobileMenu-links');

    menuOpenButton.addEventListener('click', () => {
      console.log('menuButtonOpen clicked');
      menuOpenButton.classList.toggle('hidden');
      menuCloseButton.classList.toggle('hidden');
    });

    menuCloseButton.addEventListener('click', () => {
      console.log('menuButtonClose clicked')
      menuCloseButton.classList.toggle('hidden');
      menuOpenButton.classList.toggle('hidden');
    });
};

mobileMenuOpenAndClose(); 
 /* Hamburger Menu */
.nav-button-menuOpen {
  cursor: pointer;
  display: inline-block;
  animation: fadeIn 0.2s;
}
.nav-button-menuOpen div {
  width: 30px;
  height: 30px;
  height: 3px;
  margin: 5px 0;
  background-color: black;
}
.nav-button-menuClose {
  cursor: pointer;
  display: inline-block;
  animation: fadeIn 0.2s;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
}

@keyframes fadeIn {
  from { opacity: 0 }
  to { opacity: 100 }
}

.nav-button-menuClose span {
  color: black;
  font-size: 2rem;
}

.hidden {
  display: none
} 
 <div class="nav-button-menuOpen">
  <div class="menuOpen-line"></div>
  <div class="menuOpen-line"></div>
  <div class="menuOpen-line"></div>
</div>
<div class="nav-button-menuClose hidden">
  <span>x</span>
</div> 

Ответ №2:

Это связано с тем, что вы добавляете nav-button-toggle класс к .nav-button-menuClose элементу, но в селекторе css вы пытаетесь применить непрозрачность, если у родителя этого элемента есть nav-button-toggle класс:

nav .nav-button-toggle .nav-button-menuClose { (в основном у вас есть дополнительное пространство между классами в этом селекторе)

 const mobileMenuOpenAndClose = () => {
    const menuOpenButton = document.querySelector('.nav-button-menuOpen');
    const menuCloseButton= document.querySelector('.nav-button-menuClose');
    const navMobileMenu = document.querySelector('.nav-mobileMenu');
    const navMobileMenuLinks = document.querySelectorAll('.nav-mobileMenu-links');

    menuOpenButton.addEventListener('click', () => {
      console.log('menuButtonOpen clicked');
      menuOpenButton.classList.toggle('nav-button-toggle');
      menuCloseButton.classList.toggle('nav-button-toggle');
    });

    menuCloseButton.addEventListener('click', () => {
      console.log('menuButtonClose clicked')
      menuCloseButton.classList.toggle('nav-button-toggle');
      menuOpenButton.classList.toggle('nav-button-toggle');
    });
};

mobileMenuOpenAndClose(); 
 /* Hamburger Menu */
nav .nav-button-menuOpen {
  justify-self: end;
  cursor: pointer;
  display: inline-block;
  opacity: 1;
}
nav .nav-button-menuOpen div {
  width: 30px;
  height: 30px;
  height: 3px;
  margin: 5px 0;
  background-color: var(--color-black);
  transition: all;
}
nav .nav-button-menuClose {
  justify-self: end;
  cursor: pointer;
  display: inline-block;
  opacity: 0;
}
nav .nav-button-menuClose span {
  color: var(--color-black);
  font-size: 1rem;
  transition: all;
}
nav .nav-button-toggle .menuOpen-line  {
  opacity: 0;
}
nav .nav-button-toggle.nav-button-menuClose { 
  opacity: 1; 
} 
 <nav>
<div class="nav-button-menuOpen">
  <div class="menuOpen-line">menu1</div>
  <div class="menuOpen-line">menu2</div>
  <div class="menuOpen-line">menu3</div>
</div>
<div class="nav-button-menuClose">
  <span>x</span>
</div>
</nav> 

Что касается анимации, так как вы меняете только непрозрачность, анимировать больше нечего, так как другие изменения стиля между состояниями не применяются.

Ответ №3:

Вы можете добиться этого с помощью одного .nav-меню-переключить элемент в open и close меню с помощью события одного клика JavaScript .

 document.querySelector('.nav-menu-toggle').addEventListener('click', (t) => {
    t.target.classList.toggle('active');
}); 
 /* Hamburger Menu */
:root{
    --color-black : #000
}
nav{
    background-color: #f2f2f2;
    padding: 20px;
}
nav .nav-menu-toggle {
    width: 30px;
    height: 30px;
    display: block;
    cursor: pointer;
    overflow: hidden;
}
nav .nav-menu-toggle div{
    width: 100%;
    height: 3px;
    margin-bottom: 10px;
    background-color: #000;
    transition: 0.5s transform cubic-bezier(0.075, 0.82, 0.165, 1);
    pointer-events: none;
}
nav .nav-menu-toggle.active div{
    background-color: #ff0000;
}
nav .nav-menu-toggle.active div:nth-child(1){
    transform: rotate(-45deg);
    transform-origin: 110% 9px;
}
nav .nav-menu-toggle.active div:nth-child(2){
    transform: scale(0);
}
nav .nav-menu-toggle.active div:nth-child(3){
    transform: rotate(45deg);
    transform-origin: 95% -4.5px;
} 
 <nav>
  <div class="nav-menu-toggle">
    <div></div>
    <div></div>
    <div></div>
  </div>
</nav>