Добавить класс при наведении с помощью JavaScript

Я хочу добавить класс в ul, который находится внутри моего единственного элемента li в nav. Моя проблема в том, что я хочу показать список при наведении курсора, а затем щелкнуть что-то по нему, но когда я вводю мышь, отображается это меню li, и когда я хочу спуститься и щелкнуть что-то, меню исчезает. Я хочу сделать это на ванильном JavaScript.

document.addEventListener('DOMContentLoaded', function () {
    var dropdownItem = document.querySelector('.dropdown-item');
    var dropdown = document.querySelector('.dropdown');

    dropdownItem.addEventListener('mouseenter', function (e) {
        dropdown.classList.add('dropdown-show');
    });
    dropdownItem.addEventListener('mouseleave', function () {
        dropdown.classList.remove('dropdown-show');
    })

})
  .menu {
     list-style: none;
     display: flex;
     width: 30%;
     justify-content: space-between;
     align-items: center;
  }
   .menu li {
     position: relative;
  }
   .menu li a {
     color: #999;
     text-decoration: none;
  }
   .menu .dropdown-item {
     position: relative;
  }
   .menu .dropdown-item .dropdown {
     position: absolute;
     list-style: none;
     top: 5px;
     padding-top: 40px;
     left: -30px;
     visibility: hidden;
     opacity: 0;
     transition: 0.3s;
  }
   .menu .dropdown-item .dropdown .triangle {
     border: 10px solid transparent;
     border-bottom-color: #000;
     width: 0;
     top: 20px;
     left: 50%;
     transform: translateX(-50%);
     position: absolute;
  }
   .menu .dropdown-item .dropdown.dropdown-show {
     opacity: 1;
     visibility: visible;
  }
   .menu .dropdown-item .dropdown li {
     background-color: #000;
     padding: 10px 20px;
     font-weight: lighter;
  }
<ul class = "menu">
    <li class = "dropdown-item"><a href = "#">O Firmie</a>
        <ul class = "dropdown">
            <div class = "triangle"></div>
            <li><a href = "#">Aktualności</a></li>
            <li><a href = "#">Nasz team</a></li>
            <li><a href = "#">Historia</a></li>
        </ul>
    </li>
    <li><a href = "#">Galeria</a></li>
    <li><a href = "#">Kontakt</a></li>
</ul>

Почему бы не использовать для этого css?

Domenik Reitzner 17.09.2018 17:16

Вероятно, вы могли бы сделать это полностью с помощью CSS, если вы просто хотите показать / скрыть что-то.

Mathias Rechtzigel 17.09.2018 17:16

@DomenikReitzner Я знаю, как это сделать в css, но мне нужно сделать это с помощью JS, я имею в виду, что кто-то хочет :)

Freestyle09 17.09.2018 17:16

Можете ли вы изменить его, чтобы включить обычный CSS, чтобы он мог работать во фрагменте?

Reinstate Monica Cellio 17.09.2018 17:22

Собирался написать то же самое ....

Domenik Reitzner 17.09.2018 17:23

Готово, можете проверить сейчас?

Freestyle09 17.09.2018 17:25

Ага - теперь это работает, как я ожидал. Попробуйте запустить фрагмент и сообщите нам, что с ним не так.

Reinstate Monica Cellio 17.09.2018 17:26

Лол ... Почему в моем браузере не работает ?? Я скопировал код, кто-нибудь может мне объяснить?

Freestyle09 17.09.2018 17:28

Выполняется ли сценарий до того, как меню будет добавлено на страницу?

Reinstate Monica Cellio 17.09.2018 17:28

@ Freestyle09 какой браузер вы используете? Не могу воспроизвести

Tom M 17.09.2018 17:28

Google Chrome, и я чувствовал, что он должен работать, но не знаю, почему это не так

Freestyle09 17.09.2018 17:29

Извини - не обращай на меня внимания. Не обратил внимания на обработчик DOMContentLoaded.

Reinstate Monica Cellio 17.09.2018 17:31

Лол, я добавил z-index, и он работает ... Каким-то образом другой div заблокировал его ... Лол, я не могу поверить в то, что вижу ... Кто-то может добавить это в качестве ответа

Freestyle09 17.09.2018 17:31

Я использую firefox и запускаю ваш код, он работает правильно! Я не могу понять твою проблему!

DvlprXCII 17.09.2018 17:31

Нет, вы его нашли, поэтому никто больше не должен его добавлять. Добавь сам.

Reinstate Monica Cellio 17.09.2018 17:32

И с браузером Chrome у меня тоже не было проблем

Domenik Reitzner 17.09.2018 17:32
Поведение ключевого слова "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) для оценки ваших знаний,...
3
16
12 416
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вы можете использовать что-то вроде этого:

<ul class = "dropdown" onmouseover = "hoverTrue($event)" onmouseout = "hoverOut($event)">

function hoverTrue(event) {
 event.target.style.display = 'block'; 
 //or add class
 event.target.setAttribute('class', 'something');
}

function hoverOut(event) {
 event.target.style.display = 'none';
 //or add class
 event.target.setAttribute('class', 'something');
}

Если вы хотите использовать переход, вы не можете стилизовать отображение

Freestyle09 17.09.2018 17:27

@ Freestyle09 можно использовать opacity и pointer-events: none

Tom M 17.09.2018 17:28

Это не актуально. Код OP действительно работает (без простого использования встроенных обработчиков, которые ничего не меняют).

Reinstate Monica Cellio 17.09.2018 17:29

Использование встроенных обработчиков событий в HTML - не лучшая практика. Установка класса для элемента с использованием setAttribute гораздо более проблематична (она стирает существующие классы в элементе), чем использование classList.add().

Heretic Monkey 17.09.2018 17:30
Ответ принят как подходящий

Z-index по умолчанию моего li каким-то образом находился под другим div ...

.menu {
    list-style: none;
    display: flex;
    width: 30%;
    justify-content: space-between;
    align-items: center;
    z-index: 999;
}

Теперь он работает отлично, и меню не исчезает при отпускании мыши в этом меню.

Спасибо ребята за помощь

Используйте событие «mouseover» вместо «mouseenter» и «mouseout» вместо «mouseleave».

напишите console.info ('hi') в событии наведения курсора мыши, и вы увидите, почему бы и нет

Freestyle09 17.09.2018 21:40

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

Проблема с вашим кодом заключается в том, что вы добавляете событие mouseleave в тот самый элемент (dropdown-item), который показывает ваше раскрывающееся меню в первую очередь. Событие mouseleave должно быть в родительском (раскрывающемся списке).

Вот код:

document.getElementsByClassName("dropdown-item")[0].addEventListener("mouseover", function(e) {
    const parent = e.target.parentElement;
    if (parent && parent.tagName === "LI" && parent.classList.contains("dropdown-item")) {
        const parent = e.target.parentElement;
        parent.children[1].classList.add("active");
    }
});
    
document.getElementsByClassName("dropdown")[0].addEventListener("mouseout", function(e) {
    e.target.classList.remove("active");
});
.dropdown {
    display: none;
}
    
.active {
    display: block;
}
<ul class = "menu">
    <li class = "dropdown-item"><a href = "#">O Firmie</a>
        <ul class = "dropdown">
            <div class = "triangle"></div>
            <li><a href = "#">Aktualności</a></li>
            <li><a href = "#">Nasz team</a></li>
            <li><a href = "#">Historia</a></li>
        </ul>
    </li>
    <li><a href = "#">Galeria</a></li>
    <li><a href = "#">Kontakt</a></li>
</ul>

* Обратите внимание, что это дает вам быстрое представление о том, как это сделать. Это ни идеальный, ни эффективный код.

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