Jquery зависания, если мышь движется быстро - PullRequest
0 голосов
/ 09 ноября 2018

у меня div с классом .catalog-btn. У него есть брат .catalog-mnu (выпадающее меню) с display: none

Когда я hover на .catalog-btn, slideDown() запускается для .catalog-mnu.

.catalog-mnu появляется под .catalog-btn. Он имеет :before псевдокласс, который создает div с шириной и высотой, равной размеру .catalog-btn. Итак, что происходит: пользователь наводит на кнопку, появляется выпадающее меню, в этом меню есть элемент before, который закрывает кнопку. Так что теперь кнопка закрыта выпадающим меню .catalog-mnu. Если mouseleave вызвано для выпадающего меню, slideUp() скроет его. Вот HTML:

<div class="catalog-btn">
    <div class="catalog-btn__text">Каталог оборудования</div>
</div>
<div class="catalog-mnu">
    <ul>
        <li>Link</li>
        <li>Link</li>
        <li>Link</li>
    </ul>
</div>

Вот код jquery:

  $(document).on('mouseenter', '.catalog-btn', function() {
    $(".catalog-mnu.catalog-mnu-desktop").stop().slideDown(250);
  });

  $(document).on('mouseleave', '.catalog-mnu.catalog-mnu-desktop', function() {
    $(".catalog-mnu.catalog-mnu-desktop").stop().slideUp(250);
  });

Проблема заключается в следующем: если вы наведите курсор на кнопку, но будете очень быстро двигать мышь, до завершения анимации slideDown() появится раскрывающееся меню, но в раскрывающемся списке не будет "mouseenter". -меню. Таким образом, курсор находится не в выпадающем меню, а меню видно (хотя оно должно быть видно только при наведении). Меню не скроется, пока вы на самом деле не наведите его, а затем не будете двигать мышь.

Как я могу изменить код jquery для решения этой головоломки? Я думаю, что проблема в анимации. При наведении на кнопку - slideDown() запускается. Но если mouseleave произойдет до завершения анимации - событие 'mouseenter' не будет запущено. Если не двигать курсор быстро - все работает как положено.

Ответы [ 2 ]

0 голосов
/ 09 ноября 2018

Вы должны переместиться catalog-mnu внутрь вашего hover .

Я предлагаю вам не использовать slideDown / SlideUp в этом случае и реализовывать собственную анимацию ... что-то вроде этого:

.menu-outer {
  height: 0;
  overflow: hidden;
}

<div class="catalog-btn">
  <div>BUTTON</div>
  <div class="menu-outer"><div class="menu-inner">MENUITEM<br/>MENUITEM<br/>MENUITEM</div></div>
</div>

$(document).on('mouseenter', '.catalog-btn', function() {
  var $this = $(this);
  $this.find('.menu-outer').stop(true, false).animate({'height': $this.find('.menu-inner').outerHeight()}, 250, 'swing', function() {
    $this.find('.menu-outer').css({'height': 'auto'});
  });
});

$(document).on('mouseleave', '.catalog-btn', function() {
  var $this = $(this);
  $this.find('.menu-outer').stop(true, false).animate({'height': 0}, 250, 'swing', function() {
    $this.find('.menu-outer').css({'height': ''});
  });
});
0 голосов
/ 09 ноября 2018

У JS, как правило, возникают проблемы с мышью, когда мышь быстро движется. Альтернативой является использование CSS для анимации состояния меню с использованием псевдо-селектора :hover и свойства transition, что может быть сделано следующим образом:

.catalog-mnu {
  max-height: 0;
  overflow: hidden;
  transition: max-height 1s;
}

.catalog-btn:hover + .catalog-mnu,
.catalog-mnu:hover {
  max-height: 200px;
}
<div class="catalog-btn">
  <div class="catalog-btn__text">Каталог оборудования</div>
</div>
<div class="catalog-mnu">
  <ul>
    <li>Link</li>
    <li>Link</li>
    <li>Link</li>
  </ul>
</div>
...