некорректная работа mouseenter и mouseleave?

Почему когда отводишь курсор мыши с "Названия" на красный блок, к "Названия" не применяется _active? Спасибо

https://jsfiddle.net/uehaj49s/27/

 const catalogHeaderItem = document.querySelector('.catalog-header__item');
const catalogHeaderSubtitle = document.querySelectorAll('.catalog-header__subtitle');

if (catalogHeaderItem) {
  catalogHeaderItem.addEventListener("mouseenter", function() {
    catalogHeaderSubtitle.classList.add('_active')
  });

  catalogHeaderItem.addEventListener("mouseleave", function() {
    catalogHeaderSubtitle.classList.remove('_active')
  });


}
.bottom-header__catalog {
  max-width: 800px;
  margin: 0 auto;
  position: relative;
}

.catalog-header__block {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
   background: #f4f4f4;
}


.catalog-header__list {
  width: 30%;
  padding: 22px 30px 46px 30px;
  min-height: 1049px;
}

.catalog-header__link {
  margin: 0px 0px 10px 0px;
  list-style: none;
}

.catalog-header__subtitle {
  font-weight: 500;
  font-size:35px;
  color: #000000;
  text-decoration: none;
}

.catalog-header__subtitle._active {
  background: #ffffff;
  color: #f8ad1c;
  border-right: 3px solid #fd9d08;
}

.catalog-header__item ul li {
  list-style: none;
}

.catalog-header__item {
  display: none;
  position: absolute;
  top: 0;
  left: 30%;
  width: 100%;
  padding: 22px 20px 64px 64px;
  background: red;
}

.catalog-header__item ul {
  margin: -13px;
  display: flex;
  height: 450px;
  flex-direction: column;
  flex-wrap: wrap;
}

.catalog-header__list>li:hover .catalog-header__item {
  display: block;
}
<div class="bottom-header__catalog catalog-header">
  <div class="catalog-header__block">
    <ul class="catalog-header__list">
      <li class="catalog-header__link">
        <a href="#" class="catalog-header__subtitle">Название</a>
        <div class="catalog-header__item">
          <ul>
            <li><a href="#"></a></li>
            <li><a href="#"></a></li>
          </ul>
        </div>
      </li>
      <li class="catalog-header__link">
        <a href="#" class="catalog-header__subtitle">Название</a>
        <div class="catalog-header__item">
          <ul>
            <li><a href="#"></a></li>
            <li><a href="#"></a></li>
          </ul>
        </div>
      </li>
    </ul>
  </div>
</div>


Ответы (1 шт):

Автор решения: De.Minov

Т.к. у вас в каждом .catalog-header__link (далее без catalog-header__) находятся два нужных элемента item и subtitle, то я посчитал логичным, сделать следующее:

  1. перебрать все item и повесить слушатели на них.
  2. при срабатывание слушателя, от таргета возвращаемся наверх до link, при помощи .closest()
  3. в полученном link выбираем subtitle и ему уже ставим\удаляем класс

const items = document.querySelectorAll('.catalog-header__item'); // получаем коллекцию элементов

if(items.length > 0) { // Если их больше 0
  items.forEach(function(e) { // Проходим циклом по всем элементам
    e.addEventListener('mouseenter', function(e) {
      e.target // получаем таргет
       .closest('.catalog-header__link') // от него возвращаемся наверх до элемента .catalog-header__link
       .querySelector('.catalog-header__subtitle') // в том элементе берём `.catalog-header__subtitle`
       .classList.add('_active'); // и ему вешаем класс `active`
    });
    
    // Ниже аналогично, только с удалением класса.
    e.addEventListener('mouseleave', function(e) {
      e.target
       .closest('.catalog-header__link')
       .querySelector('.catalog-header__subtitle')
       .classList.remove('_active');
    });
  });
}
.bottom-header__catalog {
  max-width: 800px;
  margin: 0 auto;
  position: relative;
}

.catalog-header__block {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
   background: #f4f4f4;
}


.catalog-header__list {
  width: 30%;
  padding: 22px 30px 46px 30px;
  min-height: 1049px;
}

.catalog-header__link {
  margin: 0px 0px 10px 0px;
  list-style: none;
}

.catalog-header__subtitle {
  font-weight: 500;
  font-size:35px;
  color: #000000;
  text-decoration: none;
}

.catalog-header__subtitle._active {
  background: #ffffff;
  color: #f8ad1c;
  border-right: 3px solid #fd9d08;
}

.catalog-header__item ul li {
  list-style: none;
}

.catalog-header__item {
  display: none;
  position: absolute;
  top: 0;
  left: 30%;
  width: 100%;
  padding: 22px 20px 64px 64px;
  background: red;
}

.catalog-header__item ul {
  margin: -13px;
  display: flex;
  height: 450px;
  flex-direction: column;
  flex-wrap: wrap;
}

.catalog-header__list>li:hover .catalog-header__item {
  display: block;
}
<div class="bottom-header__catalog catalog-header">
  <div class="catalog-header__block">
    <ul class="catalog-header__list">
      <li class="catalog-header__link">
        <a href="#" class="catalog-header__subtitle">Название</a>
        <div class="catalog-header__item">
          <ul>
            <li><a href="#"></a></li>
            <li><a href="#"></a></li>
          </ul>
        </div>
      </li>
      <li class="catalog-header__link">
        <a href="#" class="catalog-header__subtitle">Название</a>
        <div class="catalog-header__item">
          <ul>
            <li><a href="#"></a></li>
            <li><a href="#"></a></li>
          </ul>
        </div>
      </li>
    </ul>
  </div>
</div>


Ах да, ответ на вопрос.

Почему когда отводишь курсор мыши с "Названия" на красный блок, к "Названия" не применяется _active?

Разберём код

const catalogHeaderItem = document.querySelector('.catalog-header__item');
// в примере элемента два, а `querySelector` вернёт только первый
const catalogHeaderSubtitle = document.querySelectorAll('.catalog-header__subtitle');
// А тут `querySelectorAll` вернёт NodeList - по сути массив

if(catalogHeaderItem) {
  catalogHeaderItem.addEventListener("mouseenter", function() {
    catalogHeaderSubtitle.classList.add('_active') // А тут ошибочка
    // эта переменная возвращает массив, в нём нет такого как `.classList`,
    // но он есть у значений массива.
    // ----
    // Но если переберёте все значение и выдадите класс..
    // То работать наведение будет только, если навести на первое "Название"
  });

  // Тут аналогичная ошибка
  catalogHeaderItem.addEventListener("mouseleave", function() {
    catalogHeaderSubtitle.classList.remove('_active')
  });
}
→ Ссылка