Как закрыть меню при нажатии на один из элементов?
Не понимаю почему функция closeMenu не отрабатывает
const burger = document.querySelector('.burger')
const mobileMenu = document.querySelector('.mobile-menu')
const mainMenu = document.querySelector('.main-menu').cloneNode(true)
const headerCeos = document.querySelector('.header__ceos').cloneNode(true)
const headerCeosItems = document.querySelectorAll('.header__ceos-item')
const body = document.body
burger.addEventListener('click', burgerHandler)
function burgerHandler(e) {
e.preventDefault()
mobileMenu.classList.toggle('open')
burger.classList.toggle('active')
body.classList.toggle('noscroll')
renderMobileMenu()
}
function renderMobileMenu() {
mobileMenu.append(mainMenu, headerCeos)
}
headerCeosItems.forEach(el => el.addEventListener('click', closeMenu))
function closeMenu() {
mobileMenu.classList.remove('open')
}
.main-menu__list {
list-style-type: none;
margin: 0;
padding: 0;
text-align: center;
}
.main-menu__item {
display: inline-block;
margin: 0 10px;
position: relative;
}
.burger {
background: transparent;
border: none;
padding: 0;
cursor: pointer;
position: relative;
vertical-align: middle;
width: 26px;
height: 16px;
margin-left: 10px;
}
.burger__icon,
.burger__icon::after,
.burger__icon::before {
background-color: blue;
position: absolute;
width: 26px;
height: 2px;
transition: all .2s ease-out;
display: block;
right: 0;
}
.burger__icon::after,
.burger__icon::before {
content: '';
}
.burger__icon::before {
top: -7px;
}
.burger__icon::after {
bottom: -7px;
}
.burger.active .burger__icon {
background-color: transparent;
}
.burger.active .burger__icon::before {
top: 0;
transform: rotate(45deg);
}
.burger.active .burger__icon::after {
bottom: 0;
transform: rotate(-45deg);
}
.header__ceos {
text-align: center;
margin-top: 30px;
}
.header__ceos-item {
margin: 0 10px;
}
.mobile-menu {
position: fixed;
top: 30px;
right: -100%;
width: 100%;
background-color: grey;
z-index: 10;
padding: 30px 0;
transition: all .3s ease-out;
}
.mobile-menu.open {
right: 0;
}
.mobile-menu .header__ceos-item {
color: #fff;
}
<button class="burger">
<i class="burger__icon"></i>
</button>
<nav class="main-menu">
<ul class="main-menu__list">
<li class="main-menu__item">
<a class="main-menu__link" href="#">Пункт 1</a>
</li>
<li class="main-menu__item">
<a class="main-menu__link" href="#">Пункт 2</a>
</li>
<li class="main-menu__item">
<a class="main-menu__link" href="#">Пункт 3</a>
</li>
</ul>
</nav>
<div class="header__ceos">
<a class="header__ceos-item" href="#">
<span class="header__ceos-name">Имя 1</span>
</a>
<a class="header__ceos-item" href="#">
<span class="header__ceos-name">Имя 2</span>
</a>
<a class="header__ceos-item" href="#">
<span class="header__ceos-name">Имя 3</span>
</a>
</div>
<div class="mobile-menu"></div>
Ответы (1 шт):
Когда клонируется Node здесь const headerCeos = document.querySelector('.header__ceos').cloneNode(true), существует только переменная, содержащая элемент, но сам этот элемент на странице не появляется, а появляется только при выполнении mobileMenu.append(mainMenu, headerCeos).
Вот только mobileMenu.append(mainMenu, headerCeos) выполняется при клике на бургер, а выбор всех элементов const headerCeosItems = document.querySelectorAll('.header__ceos-item') осуществляется сразу при выполнении скрипта и он вернёт только три элемента из main-menu, так как в mobile-menu на момент выполнения не существует элементов.
Ну и тогда запись headerCeosItems.forEach(el => el.addEventListener('click', closeMenu)) назначит обработчики события только на три элемента .header__ceos-item, которые принадлежат элементу main-menu, а элементы .header__ceos-item, принадлежащие mobile-menu, появятся на странице только после клика на бургер и не будут иметь обработчиков события click.
Немного сумбурно получилось, но, надеюсь, смысл понятен.
Ниже рабочий вариант с внесением поиска элементов .header__ceos-item и назначения им обработчиков события в функцию рендера мобильного меню после того, как в mobile-menu добавились элементы.
Либо в вашем исходном коде можно просто mobileMenu.append(mainMenu, headerCeos) вставить сразу после const headerCeos = document.querySelector('.header__ceos').cloneNode(true), а объявление функции renderMobileMenu() и её вызов в burgerHadler удалить.
const burger = document.querySelector('.burger')
const mobileMenu = document.querySelector('.mobile-menu')
const mainMenu = document.querySelector('.main-menu').cloneNode(true)
const headerCeos = document.querySelector('.header__ceos').cloneNode(true)
const body = document.body
burger.addEventListener('click', burgerHandler)
function burgerHandler(e) {
e.preventDefault()
mobileMenu.classList.toggle('open')
burger.classList.toggle('active')
body.classList.toggle('noscroll')
renderMobileMenu()
}
function renderMobileMenu() {
mobileMenu.append(mainMenu, headerCeos)
const headerCeosItems = mobileMenu.querySelectorAll('.header__ceos-item')
headerCeosItems.forEach(el => el.addEventListener('click', closeMenu))
}
function closeMenu() {
mobileMenu.classList.remove('open')
}
.main-menu__list {
list-style-type: none;
margin: 0;
padding: 0;
text-align: center;
}
.main-menu__item {
display: inline-block;
margin: 0 10px;
position: relative;
}
.burger {
background: transparent;
border: none;
padding: 0;
cursor: pointer;
position: relative;
vertical-align: middle;
width: 26px;
height: 16px;
margin-left: 10px;
}
.burger__icon,
.burger__icon::after,
.burger__icon::before {
background-color: blue;
position: absolute;
width: 26px;
height: 2px;
transition: all .2s ease-out;
display: block;
right: 0;
}
.burger__icon::after,
.burger__icon::before {
content: '';
}
.burger__icon::before {
top: -7px;
}
.burger__icon::after {
bottom: -7px;
}
.burger.active .burger__icon {
background-color: transparent;
}
.burger.active .burger__icon::before {
top: 0;
transform: rotate(45deg);
}
.burger.active .burger__icon::after {
bottom: 0;
transform: rotate(-45deg);
}
.header__ceos {
text-align: center;
margin-top: 30px;
}
.header__ceos-item {
margin: 0 10px;
}
.mobile-menu {
position: fixed;
top: 30px;
right: -100%;
width: 100%;
background-color: grey;
z-index: 10;
padding: 30px 0;
transition: all .3s ease-out;
}
.mobile-menu.open {
right: 0;
}
.mobile-menu .header__ceos-item {
color: #fff;
}
<button class="burger">
<i class="burger__icon"></i>
</button>
<nav class="main-menu">
<ul class="main-menu__list">
<li class="main-menu__item">
<a class="main-menu__link" href="#">Пункт 1</a>
</li>
<li class="main-menu__item">
<a class="main-menu__link" href="#">Пункт 2</a>
</li>
<li class="main-menu__item">
<a class="main-menu__link" href="#">Пункт 3</a>
</li>
</ul>
</nav>
<div class="header__ceos">
<a class="header__ceos-item" href="#">
<span class="header__ceos-name">Имя 1</span>
</a>
<a class="header__ceos-item" href="#">
<span class="header__ceos-name">Имя 2</span>
</a>
<a class="header__ceos-item" href="#">
<span class="header__ceos-name">Имя 3</span>
</a>
</div>
<div class="mobile-menu"></div>