如果鼠标快速移动,jQuery悬停问题

时间:2018-11-09 14:55:30

标签: jquery events hover

我有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()动画制作完成之前,将显示下拉菜单,但不会出现{{ 1}}上的下拉菜单。因此,光标不在下拉菜单上,但菜单可见(尽管仅在悬停时才可见)。菜单只有在您将鼠标悬停然后将其移出后才会隐藏。

如何更改jquery代码以解决此难题?我想这个问题出在动画上。将鼠标悬停在按钮上时-"mouseenter"开始。但是,如果slideDown()发生在动画完成之前-mouseleave事件不会触发。如果不快速移动光标-一切都会按预期进行。

2 个答案:

答案 0 :(得分:2)

在鼠标快速移动的鼠标事件中,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>

答案 1 :(得分:0)

您应将 catalog-mnu 移至悬停内。

在这种情况下,我建议您不要使用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': ''});
  });
});