Как я могу использовать ванильный JavaScript для настройки мобильной навигации, при которой щелчок по родительскому элементу навигации будет выполнять поиск дочернего элемента ul и добавлять класс?

Я пытаюсь настроить мобильную навигацию так, чтобы нажатие на «родительский» элемент навигации осуществляло поиск 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>

Я не уверен, что понимаю. При нажатии на родительское меню уже открывается подменю. Вы просто просите закрыть открытые подменю при выборе другого?

Spencer May 14.04.2024 00:08

Щелчок по родительскому меню не открывает подменю, по крайней мере, на моем сайте WordPress. У меня была пустая ссылка, и я попробовал либо сделать событие щелчка пустым тегом <a>, либо <li> элемента навигации. Ни один из них не добавляет активный класс в подменю ul. Я думаю, что что-то в каждом моем цикле не настроено должным образом? Проблема, которую я пытался решить, заключалась в том, что нажатие на стрелку раскрывающегося списка открывало ссылку li, поэтому я хочу удалить ссылку и сделать так, чтобы при нажатии на li вместо этого открывалось подменю.

Mrich 14.04.2024 00:14

Ах, добавьте document.addEventListener('DOMContentLoaded', function () { /*yourcodehere*/ }); вокруг вашего JavaScript. Скорее всего, он запускается до того, как документ будет напечатан.

Spencer May 14.04.2024 00:19
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
3
63
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я нашел некоторые ошибки в коде и исправил их.

Во-первых, я добавил здесь > перед 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, а не тот пример, который я предоставил.

Mrich 15.04.2024 20:47

Другие вопросы по теме