延迟jQuery mouseleave或toggleClass

时间:2017-04-04 18:09:28

标签: jquery drop-down-menu

我有一个非常简单的悬停菜单,我正在试图找出如何处理时间。

目标是将mouseleave事件延迟500,和/或不对其他菜单项的快速传递作出反应。

基本功能:

$('.button').on({
  mouseenter: function () {
    $(this).children('.menu').addClass('open');
  },
  mouseleave: function() {
    $(this).children('.menu').removeClass('open');
  }, 
});

这个问题的主要问题是按钮和菜单之间的像素间隙 - 当用户将鼠标移向菜单时会触发mouseleave功能。

第二个烦恼是当鼠标快速通过兄弟按钮时,它们也会触发mouseenter功能。

我也试过但没有反应......

mouseleave: function() {

  setTimeout(function () {
    $(this).children('.menu').removeClass('open');
  }, 500);},

});

我也尝试过使用

.delay(500).queue(function(){
  $(this).removeClass("open").dequeue();

但对我来说似乎不稳定。

console.log($.ui.version)打印1.11.4

2 个答案:

答案 0 :(得分:1)

考虑等待500毫秒,然后检查您正在查看的情况(悬停与否)是否仍然存在。

如果是,然后采取适当的行动。

$('.button').on({
  mouseenter: function() {
    waitEnterExit(this, true);
  },
  mouseleave: function() {
    waitEnterExit(this, false);
  },
});


function waitEnterExit(el, inside) {
  var button = $(el);

  setTimeout(function() {
    var hovered = button.is(':hover');

    if (hovered && inside)
      button.children('.menu').addClass('open');
    else if (!hovered && !inside)
      button.children('.menu').removeClass('open');
  }, 500);
}
p {
  display: none;
}

.open {
  display: block;
}

.button {
  border: 1px solid red;
  margin-bottom: .5em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class=button>1
  <p class=menu>inner</p>
</div>
<div class=button>2
  <p class=menu>inner</p>
</div>
<div class=button>3
  <p class=menu>inner</p>
</div>
<div class=button>4
  <p class=menu>inner</p>
</div>

答案 1 :(得分:1)

上面的回答是正确的,但我只是想做一个说明(不能评论,因为声誉很低,所以我把它留作答案)。

请注意,您使用的mouseleave在这种情况下无法删除类。

mouseleave: function() {
  //Won't remove .open
  setTimeout(function () {
    $(this).children('.menu').removeClass('open');
  }, 500);},
});

会发生什么,setTimeout函数中的$(this)是Window,而不是你的按钮。如果要定位按钮,则必须将其传递给setTimeout函数。一种方法是使用 this 创建变量。您可以通过在setTimeout函数内部和外部使用$(this)调用console.log来测试它,以查看在控制台中打印的内容。

mouseleave: function() {
  // caller now is the equivalent to this
  var caller = this;
  setTimeout(function () {
    // $(this) equivalent to the .button in this case
    $(caller).children('.menu').removeClass('open');
  }, 500);},
});