我正在尝试以非常特殊的方式制作菜单: 1)当菜单点悬停时,子菜单会过渡出现 2)再次移开鼠标后,子菜单会在转换消失之前保持一秒钟 3)如果我悬停另一个菜单项,任何剩余的子菜单(尚未转移)将立即消失。
我一直试图这样做,但我一直在遇到无法解释的错误。
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/ 在这种情况下,菜单完全按照我想要的方式完成ALMOST。它正在完成我要求的所有这三件事,但是如果我从一个菜单项直接转到另一个菜单项,则传入的一个没有预期的CSS转换。 我怀疑这可能是由于新显示的子菜单变为:在jQuery .mouseLeave()函数之前悬停(在我的.hover函数的第二部分中)已经在“incoming”子菜单上执行了.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);
}
);
现在这完全符合我的要求。除了一些子菜单外。 对于我的生活,我无法弄清楚为什么他们中的一些人不应该被隐藏。我无法看到一个模式,其中的一个受到这个“错误”的影响(我现在称它为缓解我自己的脾气)。
(菜单项1仅隐藏子菜单3,项目2仅隐藏3,而项目3仅隐藏2 - 这太荒谬了。)
我尝试了很多不同的解决方案。例如,将所有转换(可见性和不透明度)移动到.hover()函数的一部分而不是css:hover事件。 尝试.hover,.mouseenter,.mouseleave的所有形状和形式 尝试完全抛弃.hide()和.show(),只使用可见性和不透明度,但使jQuery代码改变每个mouseevent的TRANSITION速度和延迟。这在完全不同的浏览器和模拟器中完全不同。
所以现在我累了。我感觉很瘦,有点拉长,就像黄油刮得太多面包一样。
帮帮我,Stackoverflow。你是我唯一的希望。
编辑: 如果我让JS处理转换而不是使用.hide / .show,它的外观如下:
$(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;
}
愚蠢,对吗?花了几个小时才发现这只是为了发现它很糟糕。还是我比我想的更接近?
答案 0 :(得分:0)
我首先要强调在SO上撰写简明问题的重要性及其对获得答案机会的影响。我能想到的最好方法是介绍我如何提出这个问题:
我想尝试在另一个兄弟菜单项悬停时取消对菜单项的退出过渡效果。以下是我的尝试:
<!-- /* your existing code here, added using the snippet tool */ -->
我认为如果能够简明扼要地提出问题,我们会更快更好地回答你的问题。我可能错了。 :)
现在,我猜你下面的代码片段是对的吗?
$('.menu-item').on('mouseenter', function(){
$('.menu-item').addClass('hide-children');
$(this).removeClass('hide-children');
setTimeout(function(){
$('.menu-item').removeClass('hide-children');
}, 42)
})
&#13;
/* 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);
}
&#13;
<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>
&#13;