Как открыть подменю с помощью JavaScript?

Как настроить этот код, чтобы он корректно обрабатывал меню с тремя уровнями вложенности, добавляя класс "_active" на третьем уровне при клике на соответствующий пункт меню? В настоящее время этот код работает только для двух уровней вложенности меню, и класс "_active" не добавляется на третьем уровне.
  • 2 февраля 2024 г. 9:01
Ответы на вопрос 2
Чтобы обработать меню с тремя уровнями вложенности, вам нужно изменить JavaScript код таким образом, чтобы он учитывал дополнительный уровень и добавлял класс "_active" на элементы третьего уровня. Допустим, что у вас есть следующая структура HTML для меню:

```html
<ul class="menu">
    <li class="menu-item">
        <a href="#">Пункт меню 1</a>
        <ul class="submenu">
            <li class="submenu-item">
                <a href="#">Подменю 1-1</a>
                <ul class="submenu">
                    <li class="submenu-item">
                        <a href="#">Подменю 1-1-1</a>
                    </li>
                    <!-- Другие пункты подменю третьего уровня -->
                </ul>
            </li>
            <!-- Другие пункты подменю второго уровня -->
        </ul>
    </li>
    <!-- Другие пункты главного меню -->
</ul>
```

Добавим JavaScript код, который позволил бы открыть подменю третьего уровня и добавить класс "_active":

```javascript
// Получение всех пунктов меню первого уровня
var menuItems = document.querySelectorAll('.menu-item');

// Функция для добавления обработчика событий
function setupMenu(items) {
    for (var i = 0; i < items.length; i++) {
        // Если текущий пункт содержит подменю, настраиваем обработчик клика
        if (items[i].querySelector('.submenu')) {
            items[i].addEventListener('click', function(event) {
                var submenu = this.querySelector('.submenu');
                if (submenu) {
                    event.preventDefault(); // предотвратить стандартное поведение ссылки
                    submenu.classList.toggle('_active'); // переключаем класс для отображения подменю
                }

                // Закрыть открытые подменю ниже уровнем
                var otherActiveSubmenus = this.parentNode.querySelectorAll('.submenu._active');
                Array.prototype.forEach.call(otherActiveSubmenus, function(activeSubmenu) {
                    if (!activeSubmenu.contains(event.target)) {
                        activeSubmenu.classList.remove('_active');
                    }
                });
            });
            
            // Рекурсивно настраиваем для всех вложенных подменю
            var nestedSubmenus = items[i].querySelectorAll('.submenu-item');
            if (nestedSubmenus.length > 0) {
                setupMenu(nestedSubmenus);
            }
        }
    }
}

setupMenu(menuItems);

// Останавливаем всплытие события клика в документе для ссылок в подменю
document.addEventListener('click', function(event) {
    var isClickInsideMenu = event.target.closest('.menu-item');
    if (!isClickInsideMenu) {
        var activeSubmenus = document.querySelectorAll('.submenu._active');
        Array.prototype.forEach.call(activeSubmenus, function(activeSubmenu) {
            activeSubmenu.classList.remove('_active');
        });
    }
}, true);
```

Этот код следует за тем, чтобы открыть или закрыть подменю при клике на пункт меню, а также закрыть все активные подменю если клик был совершен вне меню. Кроме того, функция `setupMenu` рекурсивно обрабатывает все элементы подменю, доходя до любого уровня вложенности.

Убедитесь, что ваш HTML и CSS соответствующим образом настроены для работы с добавленным классом `_active` – в CSS должны быть правила, которые определяют видимость или другие стилистические изменения для подменю, когда этот класс применяется.
Код жесть конечно. 
Помогло - отметь решением.
Похожие вопросы