跟踪悬停的元素并忽略特定时间范围内的休息



当我将鼠标悬停在.first元素上并且如果没有其他元素具有类.open时,我想立即添加该类并显示其子列表,如果没有,我想等待600ms。整个逻辑是我想忽略悬停在那些600ms.first兄弟姐妹上,所以如果一个人处于活动状态并且我将鼠标悬停在任何兄弟姐妹上,如果我在该时间范围内向后移动,我仍然想显示原始子列表。

通过我目前的尝试,我得到了一个闪烁的switheroo表演:

$('.first').hover(function(){
    var cEle = $(this);
    if($('.first.open').length > 0){
      setTimeout(function(){ 
        if($(cEle).hover()){
          $('.first.open').removeClass('open');
          $(cEle).addClass('open');
        }
      }, 600);
    }
    else{
      $(this).addClass('open');
    }
});
.menu{float:left; width:450px; margin:0; padding:0; list-style-type:none; list-style:none;}
.first{float:left; width:150px; text-align:center; margin:0; padding:0; background:white; position:relative;}
.first:hover{background:#ccc;}
.inner{float:left; width:450px; margin:0; padding:0; display:none; position:absolute; left:0; top:100%; background:#e8e8e8;}
.inner li{float:left; width:100%; margin:0; padding:0;}
/*.first:hover .inner{display:block;}*/
.first.open .inner{display:block;}
<ul class="menu">
  <li class="first">Item
    <ul class="inner">
      <li>i-item</li>
      <li>i-item</li>
      <li>i-item</li>
    </ul>
  </li>
  <li class="first">Item
    <ul class="inner">
      <li>i-item</li>
      <li>i-item</li>
      <li>i-item</li>
    </ul>
  </li>
  <li class="first">Item
    <ul class="inner">
      <li>i-item</li>
      <li>i-item</li>
      <li>i-item</li>
    </ul>
  </li>
</ul>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

我更喜欢mouseenter和mouseleave事件,并在鼠标离开菜单项时利用clearTimeout销毁setTimeout

已更新:根据评论的要求在特定时间后提供关闭计时器

var timer = null;
var closeTimer = null;
var closeTimeout = 600;
function openMenu(el) {
   $('.first').removeClass('open');
   $(el).addClass('open');
}
$('.first').mouseleave(function() {
    if(timer) clearTimeout(timer);
    closeTimer = setTimeout(function() {
        $('.first').removeClass('open');
    }, closeTimeout);
});
$('.first').mouseenter(function(){
   if(closeTimer) clearTimeout(closeTimer);
   var cEle = this;
   if($('.first.open').length > 0) {
       timer = setTimeout(function(){ 
          openMenu(cEle);
       }, 600);
   } else {
       openMenu(cEle);
   }
});
.menu{float:left; width:450px; margin:0; padding:0; list-style-type:none; list-style:none;}
.first{float:left; width:150px; text-align:center; margin:0; padding:0; background:white; position:relative;}
.first:hover{background:#ccc;}
.inner{float:left; width:450px; margin:0; padding:0; display:none; position:absolute; left:0; top:100%; background:#e8e8e8;}
.inner li{float:left; width:100%; margin:0; padding:0;}
/*.first:hover .inner{display:block;}*/
.first.open .inner{display:block;}
<ul class="menu">
  <li class="first">Item
    <ul class="inner">
      <li>i-item</li>
      <li>i-item</li>
      <li>i-item</li>
    </ul>
  </li>
  <li class="first">Item
    <ul class="inner">
      <li>i-item</li>
      <li>i-item</li>
      <li>i-item</li>
    </ul>
  </li>
  <li class="first">Item
    <ul class="inner">
      <li>i-item</li>
      <li>i-item</li>
      <li>i-item</li>
    </ul>
  </li>
</ul>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

最新更新