动画持续时间的鼠标悬停问题

mouseover issue with animation duration

下面是一个简单的 mouseovermouseleave 函数。

当鼠标悬停在菜单上时,它会从左边弹出,离开时又会隐藏起来。

问题是如果鼠标直接输入<ul id='reference'>,效果很好,但是如果我通过它的第一个li子输入,然后再做一个mouseleave,会花很长时间它隐藏。请查看下面的演示以了解我的意思(通过小选项卡输入鼠标然后 mouseleave,然后通过大框输入鼠标然后 mouseleave

$("#reference").on('mouseover', function() {
  $(this).animate({
    left: 0
  });
});
$("#reference").on('mouseleave', function() {
  $(this).animate({
    left: -115
  });
});
#reference{
  position: absolute;
  background-Color: white;
  box-Shadow: 0px 0px 10px #888888;
  z-Index: 100000;
  list-Style: none;
  border-Radius: 0px 5px 5px 0px;
  padding: 10px;
  padding-Bottom: 50px;
  min-Height: 300px;
  width: 120px;
  max-Width:120px;
  left: -115px;
}
#reference li:nth-child(1){
  position:relative;
  padding-top:25px;
  padding-left: 3px;
  left:30%;
  height:80px;
  width:25px; background:white;
  border-radius: 0px 15px 15px 0px; float:right;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="reference">
  <li>
    <i class='fa fa-user' style="position:relative; color:gray;"></i></li>
  <li>Welcome,</li>
  <li>Profile</li>
  <li><a>Log out</a></li>
  <li>empty</li>
</ul>

https://jsfiddle.net/cgvsbs9s/

就这么简单,用mouseenter代替mouseover jsFiddle

原因是mouseover容易从子元素中冒出事件(再次触发mouseover事件)。由于每个子元素都触发了一个新的 mouseover(带有未清除队列的 expand 动画)导致: expand 400ms * times every child triggered a mouseover = 延长的动画时间 #reference 应该保持扩展。

示例 显示 mouseovermouseenter 事件之间的 差异

var mouseover = 0, mouseout = 0, mouseenter = 0, mouseleave = 0;
$("#parent").on("mouseover mouseout mouseenter mouseleave", function(e) {
  $("#"+e.type).text(++window[e.type]);
});
*{margin:0;}
#parent{
  padding: 12px;
  background: #0cf;
  display: inline-block;
  margin-right:40px;
}
.child{
  width:50px;
  height:50px;
  background: #f0c;
  margin: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Mouseover <b id=mouseover>0</b> Mouseout <b id=mouseout>0</b></p>
<p>Mouseenter <b id=mouseenter>0</b> Mouseleave <b id=mouseleave>0</b></p>
<div id="parent">
  <div class="child"></div>
  <div class="child"></div>
</div>

使用那些事件总是这个pair/combinations

mouseenter / mouseleave
mouseover / mouseout // there's really rare occasions where you want to use this two guys

但最重要的是不要忘记有些用户使用鼠标速度很快,
多次悬停可能会结束你的动画,所以你需要使用 .stop()

清除你的动画队列(buildups)
$("#reference").on('mouseenter mouseleave', function(evt) {
  $(this).stop().animate({
    left: evt.type === 'mouseenter' ? 0 : -115
  });
});

Updated jsFiddle

好消息是你根本不需要 JS

只需将此添加到您的 CSS:

#reference {
  /* other styles... */
  left: -115px;
  transition: 0.4s;
  -webkit-transition: 0.4s;
}
#reference:hover{
  left: 0;
}

CSS-only jsFiddle