Я пытаюсь настроить мобильную навигацию так, чтобы нажатие на «родительский» элемент навигации осуществляло поиск ul подменю, содержащегося внутри, и переключало «активный» класс, чтобы он появился. Бонусные баллы за добавление функции, которая закрывает любые другие «активные» подменю при открытии нового.
В меню по умолчанию подменю будут скрыты, если к нему не будет добавлен «активный» класс, но мне нужен способ проверить, щелкнут ли родительский элемент навигации, прежде чем добавлять его в соответствующий элемент подменю внутри.
Я попробовал JS ниже (а также некоторые другие методы), но мне не хватает того, как настроить цикл, в котором он проверяет, нажат ли родительский элемент меню, и если да, то переключает активный класс на дочерний ul (подпункт). меню) внутри. Любая помощь приветствуется.
document.querySelectorAll('#menu-mobile .main-wrap ul > li').forEach((it) => {
it.addEventListener('click', (ev) => {
ev.preventDefault();
it.querySelector('.sub-menu').classList.toggle('active');
});
});#menu-mobile {
position: fixed;
top: 100px;
overflow: auto;
display: block;
height: calc(100vh - 70px);
width: 200px;
right: 0;
}
#menu-mobile .main-wrap {
overflow: hidden;
margin: 0;
min-height: calc(10vh);
position: relative;
}
#menu-mobile .main-wrap ul > li {
list-style: none;
width: 100%;
display: inline-block;
padding-left: 15px;
margin: 0;
min-height: 50px;
line-height: 50px;
border-bottom: 1px solid #000;
}
#menu-mobile .main-wrap ul > li ul {
display: none;
opacity: 0;
background-color: #333333;
transition: opacity 0.25s ease;
border-top: 1px solid #000000;
}
#menu-mobile .main-wrap ul > li ul.active {
display: block;
opacity: 1;
}
<div id = "menu-mobile">
<div class = "main-wrap">
<ul id = "menu-mobile-menu">
<li id = "menu-item-12800">
<a href = "www.google.com">Menu Item 1</a>
<ul class = "sub-menu">
<li id = "menu-item-1263" class = "menu-item menu-item-type-post_type menu-item-object-page menu-item-1263">
<a href = "www.google.com">Sub Menu Item 1</a>
</li>
</ul>
</li>
<li id = "menu-item-12800">
<a href = "www.google.com">Menu Item 1</a>
<ul class = "sub-menu">
<li id = "menu-item-1264" class = "menu-item menu-item-type-post_type menu-item-object-page menu-item-1264">
<a href = "www.google.com">Sub Menu Item 1</a>
</li>
</ul>
</li>
</ul>
</div>
</div>Щелчок по родительскому меню не открывает подменю, по крайней мере, на моем сайте WordPress. У меня была пустая ссылка, и я попробовал либо сделать событие щелчка пустым тегом <a>, либо <li> элемента навигации. Ни один из них не добавляет активный класс в подменю ul. Я думаю, что что-то в каждом моем цикле не настроено должным образом? Проблема, которую я пытался решить, заключалась в том, что нажатие на стрелку раскрывающегося списка открывало ссылку li, поэтому я хочу удалить ссылку и сделать так, чтобы при нажатии на li вместо этого открывалось подменю.
Ах, добавьте document.addEventListener('DOMContentLoaded', function () { /*yourcodehere*/ }); вокруг вашего JavaScript. Скорее всего, он запускается до того, как документ будет напечатан.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я нашел некоторые ошибки в коде и исправил их.
Во-первых, я добавил здесь > перед ul, так как он нам не нужен для подменю ul.
document.querySelectorAll('#menu-mobile .main-wrap ul > li').forEach...
document.querySelectorAll('#menu-mobile .main-wrap > ul > li').forEach...
Во-вторых, поскольку будет подменю, вам не следует размещать URL-адрес в главном меню:
<a href = "www.google.com">Menu Item 1</a>
<a href = "#">Menu Item 1</a>
И вам это больше не нужно (если только оно вам не нужно для вашего подменю):
ev.preventDefault();
Итак, для вашего JS это должно быть так:
document.querySelectorAll('#menu-mobile .main-wrap > ul > li').forEach(it => {
it.onclick = function(ev) {
document.querySelectorAll('#menu-mobile .sub-menu.active').forEach(subMenu => {
if (it.querySelector('.sub-menu') != subMenu ) subMenu.classList.remove('active');
});
it.querySelector('.sub-menu').classList.toggle('active');
}
});
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<meta name = "viewport" content = "width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#menu-mobile {
position: fixed;
top: 100px;
overflow: auto;
display: block;
height: calc(100vh - 70px);
width: 200px;
right: 0;
}
#menu-mobile .main-wrap {
overflow: hidden;
margin: 0;
min-height: calc(10vh);
position: relative;
}
#menu-mobile .main-wrap ul > li {
list-style: none;
width: 100%;
display: inline-block;
padding-left: 15px;
margin: 0;
min-height: 50px;
line-height: 50px;
border-bottom: 1px solid #000;
}
#menu-mobile .main-wrap ul > li ul {
display: none;
opacity: 0;
background-color: #333333;
transition: opacity 0.25s ease;
border-top: 1px solid #000000;
}
#menu-mobile .main-wrap ul > li ul.active {
display: block;
opacity: 1;
}
</style>
</head>
<body>
<div id = "menu-mobile">
<div class = "main-wrap">
<ul id = "menu-mobile-menu">
<li id = "menu-item-12800">
<a href = "#">Menu Item 1</a>
<ul class = "sub-menu">
<li id = "menu-item-1263" class = "menu-item menu-item-type-post_type menu-item-object-page menu-item-1263">
<a href = "#">Sub Menu Item 1</a>
</li>
</ul>
</li>
<li id = "menu-item-12800">
<a href = "#">Menu Item 1</a>
<ul class = "sub-menu">
<li id = "menu-item-1264" class = "menu-item menu-item-type-post_type menu-item-object-page menu-item-1264">
<a href = "#">Sub Menu Item 1</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
<script>
document.querySelectorAll('#menu-mobile .main-wrap > ul > li').forEach(it => {
it.onclick = function(ev) {
document.querySelectorAll('#menu-mobile .sub-menu.active').forEach(subMenu => {
if (it.querySelector('.sub-menu') != subMenu ) subMenu.classList.remove('active');
});
it.querySelector('.sub-menu').classList.toggle('active');
}
});
</script>
</body>
</html>Спасибо! это сделало это. На самом деле это не работало, пока я не изменил класс родительского элемента навигации, но это было что-то специфическое для моего сайта Wordpress, а не тот пример, который я предоставил.
Я не уверен, что понимаю. При нажатии на родительское меню уже открывается подменю. Вы просто просите закрыть открытые подменю при выборе другого?