当鼠标悬停在一个菜单项上时隐藏其他菜单项会干扰我的css转换



我正试图使一个菜单行为在一个非常特殊的方式:1)当子菜单的菜单点悬停时,子菜单会过渡出现2)再次移动鼠标后,子菜单在过渡消失之前保留一秒钟3)如果我悬停另一个菜单项,任何剩余的子菜单(尚未过渡)将立即消失。

我已经尝试这么做一段时间了,但是我总是遇到我无法解释的bug。

HTML(是的,我只是做了一些div,而不是一个列表):

    <div class="menu">
<div class="menu-item" id="item-1">
  Item 1
  <div class="menu-child" id="child-1">Child 1</div>
 </div>
 <div class="menu-item" id="item-2">
  Item 2
  <div class="menu-child" id="child-2">Child 2</div>
 </div>
 <div class="menu-item" id="item-3">
  Item 3
  <div class="menu-child" id="child-3">Child 3</div>
 </div>
 </div>
CSS:

.menu-item .menu-child {
  margin-top:10px;
  border:1px solid #000000;
  height:22px;
  visibility:hidden;
  opacity:0;
  -webkit-transition: visibility 1s 1s, opacity 1s 1s;
  transition: visibility 1s 1s, opacity 1s 1s;
}
.menu-item:hover .menu-child {
  visibility:visible;
  opacity:1;
  -webkit-transition: visibility 1s, opacity 1s;
  transition: visibility 1s, opacity 1s;
}
.menu {
  display: -webkit-flex;
  display:flex;
}
.menu-item {
  display:inline-block;
  width:32%;
  padding-left:20px;
  background:none;
  box-sizing: border-box;
  -webkit-box-sizing: border-box;
}
Javascript:

  $('#item-1').hover(
    function() {
    $("#child-2, #child-3").hide();
    },
    function() {
    $("#child-2, #child-3").show();
    }
);
   $('#item-2').hover(
    function() { 
    $("#child-1, #child-3").hide();
    },
    function() { 
    $("#child-1, #child-3").show();
    }
);
   $('#item-3').hover(
    function() { 
    $("#child-2, #child-1").hide();
    },
    function() { 
    $("#child-1, #child-2").show();
    }
);

https://jsfiddle.net/zyu9rum9/5/在这种情况下,菜单几乎完全按照我想要的方式运行。它正在做我要求的所有这三件事,但是如果我直接从一个菜单项转到另一个菜单项,进入的菜单项就会出现,而没有预期的CSS转换。我怀疑这可能是由于新显示的子菜单更改为:hover之前jQuery . mouseleave()函数(如在我的.hover函数的第二部分)已经执行。show()在"传入"子菜单。元素出现在悬停状态,这是有意义的,没有过渡到/从。

所以我试图解决这个问题,在离开子菜单之前,在所有其他子菜单上执行。show()。这是通过在。hide()之后添加。show()来实现的。https://jsfiddle.net/wtd5pxvs/2/

新JS:

  $('#item-1').mouseenter(
    function() {
    $("#child-2, #child-3").hide(0).delay(10).show(10);
    }
);
   $('#item-2').mouseenter(
    function() {
    $("#child-1, #child-3").hide(0).delay(10).show(10);
    }
);
   $('#item-3').mouseenter(
    function() {
    $("#child-2, #child-1").hide(0).delay(10).show(10);
    }
);

现在这工作正是我想要的。除了一些子菜单。对于我的生活,我不明白为什么有些人在应该藏起来的时候没有藏起来。我看不出有什么模式会受到这个"bug"的影响(我现在叫它是为了缓和我自己的脾气)。

(菜单项1只隐藏子菜单3,菜单项2只隐藏子菜单3,菜单项3只隐藏子菜单2——这太荒谬了)

我已经尝试了很多不同的解决方案。例如,将所有过渡(可见性和不透明度)移动到.hover()函数的一部分,而不是css:hover事件。尝试了各种形状和形式的。hover,。mouseenter,。mouseleave尝试将。hide()和。show()完全抛弃,只使用可见性和不透明度,但让jQuery代码改变每个鼠标事件的TRANSITION速度和延迟。这只是在完全不同的浏览器和模拟器中做了完全不同的事情。

所以现在我累了。我觉得自己很瘦,有点被拉伸了,就像黄油擦在太多的面包上。

帮助我,Stackoverflow。你是我唯一的希望。

编辑:如果我让JS处理编辑过渡而不使用。hide/,它看起来是这样的。Show at all:

$(document).ready(function(){
   $('#item-1').hover(
        function() {
        $("#child-1")
        .css("-webkit-transition", "visibility 1s, opacity 1s")
        .css("transition", "visibility 1s, opacity 1s"); 
        $("#child-2, #child-3")
        .css("-webkit-transition", "visibility 0s, opacity 1s")
        .css("transition", "visibility 0s, opacity 1s");
        },
        function() {
        $("#child-1, #child-2, #child-3")
        .css("-webkit-transition", "visibility 1s 1s, opacity 1s 1s")
        .css("transition", "visibility 1s 1s, opacity 1s 1s");
        }
    );
       $('#item-2').hover(
        function() { 
        $("#child-2")
        .css("-webkit-transition", "visibility 1s, opacity 1s")
        .css("transition", "visibility 1s, opacity 1s"); 
        $("#child-1, #child-3")
        .css("-webkit-transition", "visibility 0s, opacity 1s")
        .css("transition", "visibility 0s, opacity 1s");
        },
        function() { 
        $("#child-1, #child-2, #child-3")
        .css("-webkit-transition", "visibility 1s 1s, opacity 1s 1s")
        .css("transition", "visibility 1s 1s, opacity 1s 1s");
        }
    );
       $('#item-3').hover(
        function() { 
        $("#child-3")
        .css("-webkit-transition", "visibility 1s, opacity 1s")
        .css("transition", "visibility 1s, opacity 1s"); 
        $("#child-2, #child-1")
        .css("-webkit-transition", "visibility 0s, opacity 1s")
        .css("transition", "visibility 0s, opacity 1s"); 
        },
        function() {
        $("#child-1, #child-2, #child-3")
        .css("-webkit-transition", "visibility 1s 1s, opacity 1s 1s")
        .css("transition", "visibility 1s 1s, opacity 1s 1s");
        }
    );
        });
与CSS:

.menu-item .menu-child {
  margin-top:10px;
  border:1px solid #000000;
  visibility:hidden;
  opacity:0;
}
.menu-item:hover .menu-child {
  visibility:visible;
  opacity:1;
}

笨,对吧?花了好几个小时想出这个,结果发现它是狗屎。还是我比想象中更接近了?

我将首先强调写关于SO的简明问题的重要性,以及它对他们得到回答的机会的影响。我能想到的最好的办法是,我要怎么问这个问题:


当另一个兄弟菜单项悬停时,我试图取消菜单项上的现有过渡效果。以下是我尝试过的:

<!-- /* your existing code here, added using the snippet tool */ -->

我想SO如果能简明扼要地回答你的问题,就能更快更好地回答。不过我可能错了。:)


现在,我猜下面的片段是你来这里的目的,对吗?

$('.menu-item').on('mouseenter', function(){
	$('.menu-item').addClass('hide-children');
  $(this).removeClass('hide-children');
  setTimeout(function(){
  	$('.menu-item').removeClass('hide-children');
  }, 42)
})
/* Start of additional CSS */
.menu-item.hide-children .menu-child {
  display: none;
  -webkit-transition: visibility 0s linear 0s, opacity 0s linear 0s;
       -o-transition: visibility 0s linear 0s, opacity 0s linear 0s;
     -moz-transition: visibility 0s linear 0s, opacity 0s linear 0s;
          transition: visibility 0s linear 0s, opacity 0s linear 0s;
}
.menu-item.hide-children:hover .menu-child {
  display: block;
}
/* End of additional CSS 
Please note that in order to strictly fix your transition problem, all you need
is the CSS above added to your current CSS. You will also need the jQuery part.
However, I noticed your menu items were effectively pushing the content down 
(which, from my point of view shouldn't happen), so I took the liberty to 
change your markup a bit  and rewrite your CSS accordingly, just so you have 
an alternative.
*/
body {
  background-color: #f5f5f5;
}
.menu {
  display:-webkit-box;
  display:-webkit-flex;
  display:-moz-box;
  display:-ms-flexbox;
  display:flex;
  width: 100%;
  position: relative;
}
.menu-item {
  -webkit-box-flex: 1;
  -webkit-flex: 1 0 auto;
     -moz-box-flex: 1;
      -ms-flex: 1 0 auto;
          flex: 1 0 auto;
  background-color: rgba(255,255,255,.65);
  border-right: 1px solid transparent;
  -webkit-background-clip: content-box;
     -moz-background-clip: content-box;
       -o-background-clip: content-box;
          background-clip: content-box; 
  -webkit-transition: background-color .3s cubic-bezier(.4,0,.2,1), -webkit-box-shadow .1s linear; 
  transition: background-color .3s cubic-bezier(.4,0,.2,1), -webkit-box-shadow .1s linear; 
  -o-transition: background-color .3s cubic-bezier(.4,0,.2,1), box-shadow .1s linear; 
  -moz-transition: background-color .3s cubic-bezier(.4,0,.2,1), box-shadow .1s linear, -moz-box-shadow .1s linear; 
  transition: background-color .3s cubic-bezier(.4,0,.2,1), box-shadow .1s linear; 
  transition: background-color .3s cubic-bezier(.4,0,.2,1), box-shadow .1s linear, -webkit-box-shadow .1s linear, -moz-box-shadow .1s linear;
  text-align: center;
  text-transform: uppercase;
  line-height: 50px;
  letter-spacing: 2px;
  font-family: sans-serif;
  padding: 0;
  position: relative;
}
.menu-item:last-child {
  border-right-width: 0;
}
.menu-item:hover {
  z-index: 1;
  cursor: pointer;
}
.menu-item.fullWidthChildrenContainer {
  position: unset;
}
.children {
  border-top: 1px solid transparent;
  width: 100%;
}
.fullWidthChildrenContainer .children {
  display: -webkit-box;
  display: -webkit-flex;
  display: -moz-box;
  display: -ms-flexbox;
  display: flex;
  width: 100%;
  border-bottom-width: 1px;
}
.fullWidthChildrenContainer .children>* {
  -webkit-box-flex: 1;
  -webkit-flex-grow: 1;
     -moz-box-flex: 1;
      -ms-flex-positive: 1;
          flex-grow: 1;
  border-right-width: 1px;
}
.children>* {
  display: block;
  width: 100%;
  border: solid transparent;
  border-width: 0 0 1px;
  -webkit-box-shadow: 0 1px 3px 0 rgba(0,0,0,.1),0 1px 1px 0 rgba(0,0,0,.07),0 2px 1px -1px rgba(0,0,0,.06);
     -moz-box-shadow: 0 1px 3px 0 rgba(0,0,0,.1),0 1px 1px 0 rgba(0,0,0,.07),0 2px 1px -1px rgba(0,0,0,.06);
          box-shadow: 0 1px 3px 0 rgba(0,0,0,.1),0 1px 1px 0 rgba(0,0,0,.07),0 2px 1px -1px rgba(0,0,0,.06);
}
.children>*:last-child { border-right-width: 0;}
.menu-item:hover {
  background-color: white;
  -webkit-box-shadow: 0 1px 3px 0 rgba(0,0,0,.1),0 1px 1px 0 rgba(0,0,0,.07),0 2px 1px -1px rgba(0,0,0,.06);
     -moz-box-shadow: 0 1px 3px 0 rgba(0,0,0,.1),0 1px 1px 0 rgba(0,0,0,.07),0 2px 1px -1px rgba(0,0,0,.06);
          box-shadow: 0 1px 3px 0 rgba(0,0,0,.1),0 1px 1px 0 rgba(0,0,0,.07),0 2px 1px -1px rgba(0,0,0,.06);
}
.menu-item .menu-child {
  background-color: white;
  opacity:0;
  -webkit-transition: visibility 1s 1s, opacity 1s 1s;
  -o-transition: visibility 1s 1s, opacity 1s 1s;
  -moz-transition: visibility 1s 1s, opacity 1s 1s;
  transition: visibility 1s 1s, opacity 1s 1s;
  padding: 0 1rem;
  width: 100%;
  -webkit-background-clip:padding-box;
     -moz-background-clip:padding-box;
       -o-background-clip:padding-box;
          background-clip:padding-box;
  -webkit-box-sizing: border-box;
     -moz-box-sizing: border-box;
          box-sizing: border-box;
}
.children {
  position: absolute;
  left: 0;
  top: 100%;
}
.children>.menu-child {
  display: block;
  width: 100%;
}
.menu-item:hover .menu-child {
  opacity:1;
  -webkit-transition: visibility 1s, opacity 1s;
       -o-transition: visibility 1s, opacity 1s;
     -moz-transition: visibility 1s, opacity 1s;
          transition: visibility 1s, opacity 1s;
}
.menu-item: hover {
  background-color: rgba(255,255,255,.65);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="menu">
  <div class="menu-item fullWidthChildrenContainer" id="item-1">
    Item 1
    <div class="children">
      <div class="menu-child" id="child-11">Child 1-1</div>
      <div class="menu-child" id="child-12">Child 1-2</div>
      <div class="menu-child" id="child-13">Child 1-3</div>
      <div class="menu-child" id="child-14">Child 1-4</div>
    </div>
  </div>
  <div class="menu-item" id="item-2">
    Item 2
    <div class="children">
      <div class="menu-child" id="child-21">Child 2-1</div>
      <div class="menu-child" id="child-22">Child 2-2</div>
      <div class="menu-child" id="child-23">Child 2-3</div>
    </div>
  </div>
  <div class="menu-item fullWidthChildrenContainer" id="item-3">
    Item 3
    <div class="children">
      <div class="menu-child" id="child-31">Child 3-1</div>
      <div class="menu-child" id="child-32">Child 3-2</div>
      <div class="menu-child" id="child-33">Child 3-3</div>
    </div>
  </div>
</div>

最新更新