Показать подменю по клику, а не при наведении

Вопрос или проблема

У меня есть меню, в котором я пытаюсь сделать так, чтобы подменю появлялось по нажатию, а не при наведении. У меня есть стили для наведения, и они работают, поэтому, когда я навожу, подменю появляется как блочный элемент. Не удается избавиться от наведения и добавить событие на клик. Если родительская ссылка нажата, страница просто обновляется.

const subMenuLink = document.querySelector(".main-nav .menu .menu-item-has-children");
const subMenu = document.querySelector(".main-nav .menu .menu-item-has-children ul");

subMenuLink.addEventListener("click", toggleMenu);

function toggleMenu() {
  if (subMenu.classList.contains("visible")) {
    subMenu.classList.remove("visible");
  } else {
    subMenu.classList.add("visible");
  }
}

Мне кажется, что это на правильном пути… но пока не совсем! Есть какие-нибудь предложения, пожалуйста, спасибо.

Это добавит новые классы к вашим меню, которые будут вызываться по событию клика. Укажите по умолчанию, что вы хотите, чтобы не было наведения с CSS li:hover {display:none;}

jQuery(document).ready(function($){
    $('.nav-menu .menu-item-has-children').on("click", function(e){
            e.stopPropagation();
            if($(this).is("li")){
                if($(this).hasClass('opened')){
                    $(this).addClass('closed');
                }else{$(this).removeClass('closed');}
                $(this).siblings().children('.sub-menu').removeClass('visible');
                $(this).siblings().removeClass('current-menu-parent opened');
                $(this).toggleClass('current-menu-parent opened');
                $(this).children('.sub-menu').toggleClass('visible');
            }
            else{
                if($(this).parent().hasClass('opened')){
                    $(this).parent().addClass('closed');
                }else{$(this).parent().removeClass('closed');}
                $(this).parent().siblings().children('.sub-menu').removeClass('visible');
                $(this).parent().siblings().removeClass('current-menu-parent');
                $(this).parent().children('.sub-menu').toggleClass('visible');
                $(this).parent().toggleClass('current-menu-parent opened');
            }
    });

Ответ или решение

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

Вот шаги, которые помогут вам правильно настроить это поведение:

  1. HTML Разметка: Убедитесь, что ваша разметка меню имеет необходимую структуру. Например:
<ul class="main-nav">
    <li class="menu-item-has-children">
        <a href="#">Меню 1</a>
        <ul class="sub-menu">
            <li><a href="#">Подменю 1</a></li>
            <li><a href="#">Подменю 2</a></li>
        </ul>
    </li>
    <li><a href="#">Меню 2</a></li>
</ul>
  1. CSS Стили: Добавьте стили для подменю, чтобы они были скрыты по умолчанию:
.sub-menu {
    display: none; /* Скрыто по умолчанию */
}

.sub-menu.visible {
    display: block; /* Показать подменю, когда добавляется класс visible */
}
  1. JavaScript Код: Обновите ваш JavaScript код для обработчика кликов. Ваш код уже неплохо нацелен, но я немного его оптимизирую:
const menuItems = document.querySelectorAll(".main-nav .menu-item-has-children");

menuItems.forEach(item => {
    item.addEventListener("click", function(e) {
        e.preventDefault(); // Остановить переход по ссылке

        // Закрываем все остальные подменю
        menuItems.forEach(i => {
            if (i !== item) {
                i.querySelector(".sub-menu").classList.remove("visible");
            }
        });

        // Переключаем видимость текущего подменю
        const subMenu = this.querySelector(".sub-menu");
        subMenu.classList.toggle("visible");
    });
});

Пояснения к коду:

  • e.preventDefault(): Это предотвращает переход по ссылке при клике на элемент с классом .menu-item-has-children, что устранит проблему с перезагрузкой страницы.
  • Мы используем forEach, чтобы применить обработчик клика ко всем пунктам меню, имеющим подменю.
  • Все остальные подменю закрываются, когда открывается новое, чтобы пользователь не был перегружен слишком большим количеством открытых подменю.

Рекомендации:

  • Убедитесь, что для каждого пункта меню и его подменю используются уникальные селекторы, чтобы избежать конфликтов.
  • Рассмотрите возможность добавления анимации для более плавного отображения подменю, если это соответствует вашему дизайну.
  • Тестируйте на различных устройствах, чтобы убедиться, что функциональность работает как на десктопах, так и на мобильных устройствах.

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

Оцените материал
Добавить комментарий

Капча загружается...