Переключить класс с задержкой при наведении

Я открываю свое подменю с добавлением класса раскрыть к его родителю. Чего я хочу добиться, так это при наведении курсора на родителя, если не происходит «активного» наведения, чтобы немедленно открыть подменю, но если подменю уже показано, подождите 1 секунду, прежде чем он откроет новый. Я хочу этого из-за «плохого» движения мыши, чтобы он ждал, если мышь покинет подменю/родительский элемент, чтобы увидеть, входит ли он повторно через 1 секунду.

Я знаю, что есть куча похожих тем, но я уже сделал попытку и сейчас не вижу, что я делаю неправильно:

$('.menu > li').hover(function() {
  var ele = $(this);
  if ($('.menu li.reveal').length > 0) {
    var t = setTimeout(function() {
      if (ele.hover()) {
        $('.menu li.reveal').removeClass('reveal');
        ele.addClass('reveal');
      }
    }, 1000);
  } else {
    ele.addClass('reveal');
  }
});
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class = "menu">
  <li>
    <a href = "#">Link lv1</a>
    <ul class = "submenu">
      <li><a href = "#">Link lv2</a></li>
      <li><a href = "#">Link lv2</a></li>
      <li><a href = "#">Link lv2</a></li>
    </ul>
  </li>
  <li>
    <a href = "#">Link lv1</a>
    <ul class = "submenu">
      <li><a href = "#">Link lv2</a></li>
      <li><a href = "#">Link lv2</a></li>
      <li><a href = "#">Link lv2</a></li>
    </ul>
  </li>
  <li>
    <a href = "#">Link lv1</a>
    <ul class = "submenu">
      <li><a href = "#">Link lv2</a></li>
      <li><a href = "#">Link lv2</a></li>
      <li><a href = "#">Link lv2</a></li>
    </ul>
  </li>
</ul>
Поведение ключевого слова "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) для оценки ваших знаний,...
2
0
190
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

let timers = [], open = false;

$('.menu > li').hover(function() {
  if (this.dataset.timer) {
    timers.forEach(t => clearTimeout(t));
    clearTimeout(parseInt(this.dataset.timer));
    delete this.dataset.timer;
    open = false;
  } else if ($(this).hasClass('reveal')) {
    this.dataset.timer = setTimeout(() => {
      $(this).removeClass('reveal');
      delete this.dataset.timer;
      open = false;
    }, 1000);
    open = true;
  } else if (open) {
    timers.push(setTimeout(() => {
      $('.menu > li').removeClass('reveal');
      $(this).addClass('reveal');
    }, 1000));
  } else {
    $('.menu > li').removeClass('reveal');
    $(this).addClass('reveal');
  }
});
.submenu {
  display: none;
}

.menu > li.reveal ul {
  display: block;
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class = "menu">
  <li>
    <a href = "#">Link lv1</a>
    <ul class = "submenu">
      <li><a href = "#">Link lv2</a></li>
      <li><a href = "#">Link lv2</a></li>
      <li><a href = "#">Link lv2</a></li>
    </ul>
  </li>
  <li>
    <a href = "#">Link lv1</a>
    <ul class = "submenu">
      <li><a href = "#">Link lv2</a></li>
      <li><a href = "#">Link lv2</a></li>
      <li><a href = "#">Link lv2</a></li>
    </ul>
  </li>
  <li>
    <a href = "#">Link lv1</a>
    <ul class = "submenu">
      <li><a href = "#">Link lv2</a></li>
      <li><a href = "#">Link lv2</a></li>
      <li><a href = "#">Link lv2</a></li>
    </ul>
  </li>
</ul>

Более стилизованный вариант:

let timers = [], open = false;

$('.nav-item').hover(function() {
  if (this.dataset.timer) {
    timers.forEach(t => clearTimeout(t));
    clearTimeout(parseInt(this.dataset.timer));
    delete this.dataset.timer;
    open = false;
  } else if ($(this).hasClass('reveal')) {
    this.dataset.timer = setTimeout(() => {
      $(this).removeClass('reveal');
      delete this.dataset.timer;
      open = false;
    }, 1000);
    open = true;
  } else if (open) {
    timers.push(setTimeout(() => {
      $('.nav-item').removeClass('reveal');
      $(this).addClass('reveal');
    }, 1000));
  } else {
    $('.nav-item').removeClass('reveal');
    $(this).addClass('reveal');
  }
});
a {
  font-family: sans-serif;
  text-decoration: none;
  color: black;
}

a:hover {
  opacity: 0.5;
}

nav {
  width: 100%;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  text-align: center;
}

.nav-item {
  display: inline-block;
  list-style: none;
}

.submenu {
  display: none;
  list-style: none;
}

.nav-item ul:focus-within {
  display: block;
}

.nav-item.reveal ul {
  display: block;
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
  <div class = "nav-item">
    <a href = "#">Link lv1</a>
    <ul class = "submenu">
      <li><a href = "#">Link lv2</a></li>
      <li><a href = "#">Link lv2</a></li>
      <li><a href = "#">Link lv2</a></li>
    </ul>
  </div>
  <div class = "nav-item">
    <a href = "#">Link lv1</a>
    <ul class = "submenu">
      <li><a href = "#">Link lv2</a></li>
      <li><a href = "#">Link lv2</a></li>
      <li><a href = "#">Link lv2</a></li>
    </ul>
  </div>
  <div class = "nav-item">
    <a href = "#">Link lv1</a>
    <ul class = "submenu">
      <li><a href = "#">Link lv2</a></li>
      <li><a href = "#">Link lv2</a></li>
      <li><a href = "#">Link lv2</a></li>
    </ul>
  </div>
</nav>

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