我在创建具有特定效果的弹出菜单时遇到问题。浮出控件从 display:none 变为块,然后我使用 jquery 将不透明度从 0 设置为 1(反之亦然)。这是必要的,因为否则当元素刚刚更改其显示属性时,不会发生转换。我不认为这会传播给儿童。但是在我的浮出控件中,我有 4 列具有不透明度过渡的链接,每列都有自己的延迟,因此它们一次出现一个。但是,这在浮出控件出现时不起作用。它们立即处于不透明度:1,即使延迟时间很长,它仍然不起作用。
有没有办法解决这个问题?我知道CSS动画与同一元素上的显示更改不起作用,但是发现任何子动画也不起作用有点令人沮丧。当CSS如此简单时,我宁愿不必编写javascript。但是,如果javascript是唯一的答案,那么这将是一个容易的解决方案。
下面是一个非常简单的代码示例:
$flyout.addClass('in').animate({opacity: 1}, 200, "linear");
"in"是导致列上转换的类:
.flyout { display: none; }
.flyout.in { display: block; }
.columns li {
opacity: 0;
-webkit-transition: opacity 0.2s;
}
.flyout.in .columns li { opacity: 1; }
// delay increases with each column
.columns > li:first-child {
-webkit-transition-delay: 0.2s;
}
有没有办法解决这个问题?我知道CSS动画与同一元素上的显示更改不起作用,但是发现任何子动画也不起作用有点令人沮丧。
它不仅适用于同一元素,而且适用于整个子树 - 因为整个子树不会被渲染。
- 您可以在包装器上设置
display: block
,然后强制重排(通过使用wrapperElement.offsetHeight;
刷新样式缓冲区),然后添加一个为您的孩子设置opacity:1
的类(或执行您正在执行的任何操作来启动动画)。 - 您可以使用不同的方法来直观地隐藏包装器,例如
width: 0; height: 0; overflow: hidden; visibility: hidden;
(或者,为了更好的过渡transform: scale(0); visibility: hidden; pointer-events: none;
)
一旦涉及display:none
,您在过渡方面就完蛋了。最好的方法是避免它。很长一段时间以来,我一直在使用第二个选项,没有任何重大问题。
OP 添加了一些演示代码后编辑:
- 包装器的
.animate()
也可以在CSS中完成 - 不仅要使用以供应商为前缀的 CSS 属性
-webkit-transition
,还要使用正确的transition
-
// delay increases with each column
看起来像是一种误解。 选择器.columns > li:first-child
应用的所有元素都将具有完全相同的延迟 - 它们不会等待前一个元素完成其转换。如果你想在CSS中定义它,你必须使用:nth-child()或它的表亲之一。
如果你只想改变opacity
你可以使用JQuery的淡入和淡出函数,但如果你想要更复杂的过渡,你可以使用CSS3(这是一个非常好的库)。请参阅此演示,您可以在其中以两种不同的方式看到这一点。
您还可以像这样向类添加控件:
$("OBJECT").click(function(){
if ($("OBJECT").hasClass("CLASS")){
$("OBJECT").removeClass("CLASS");
} else {
$("OBJECT").addClass("CLASS");
}
});
以创建双向函数。
$(document).ready(function(){
$("#fadeOut").click(function(){
var duration = 500;
$("#div").fadeOut(duration);
});
$("#css").click(function(){
$("#div").addClass("out");
setTimeout(
function() {
$("#div").css("display", "none");
},
2001);
});
});
#div {
width:200px;
height:200px;
background-color:red;
text-align:center;
vertical-align:middle;
/* Animation CSS */
-webkit-animation-duration: 2s;
animation-duration: 2s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
}
/* Setup CSS3 animations */
@-webkit-keyframes out {
0% {
-webkit-transform-origin: top left;
transform-origin: top left;
-webkit-animation-timing-function: ease-in-out;
animation-timing-function: ease-in-out;
}
20%, 60% {
-webkit-transform: rotate3d(0, 0, 1, 80deg);
transform: rotate3d(0, 0, 1, 80deg);
-webkit-transform-origin: top left;
transform-origin: top left;
-webkit-animation-timing-function: ease-in-out;
animation-timing-function: ease-in-out;
}
40%, 80% {
-webkit-transform: rotate3d(0, 0, 1, 60deg);
transform: rotate3d(0, 0, 1, 60deg);
-webkit-transform-origin: top left;
transform-origin: top left;
-webkit-animation-timing-function: ease-in-out;
animation-timing-function: ease-in-out;
opacity: 1;
}
to {
-webkit-transform: translate3d(0, 700px, 0);
transform: translate3d(0, 700px, 0);
opacity: 0;
}
}
@keyframes out {
0% {
-webkit-transform-origin: top left;
transform-origin: top left;
-webkit-animation-timing-function: ease-in-out;
animation-timing-function: ease-in-out;
}
20%, 60% {
-webkit-transform: rotate3d(0, 0, 1, 80deg);
transform: rotate3d(0, 0, 1, 80deg);
-webkit-transform-origin: top left;
transform-origin: top left;
-webkit-animation-timing-function: ease-in-out;
animation-timing-function: ease-in-out;
}
40%, 80% {
-webkit-transform: rotate3d(0, 0, 1, 60deg);
transform: rotate3d(0, 0, 1, 60deg);
-webkit-transform-origin: top left;
transform-origin: top left;
-webkit-animation-timing-function: ease-in-out;
animation-timing-function: ease-in-out;
opacity: 1;
}
to {
-webkit-transform: translate3d(0, 700px, 0);
transform: translate3d(0, 700px, 0);
opacity: 0;
}
}
.out {
-webkit-animation-name: out;
animation-name: out;
}
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script type="text/javascript" src="script.js"></script>
</head>
<body>
<div id="div"></div>
<button id="fadeOut">fadeOut</button>
<button id="css">CSS3</button>
</body>
</html>
前我遇到了同样的问题,我的解决方法非常笨拙,但大部分都有效
当你改变一个,比方说,不可转换的属性,比如"显示"的东西很快就出错了,我想如果你使用一个计时器来改变不可转换的属性,几毫秒后你改变了另一个可转换的属性,它有点工作,你还需要使用另一个计时器来把事情转回来
该目录
<div class="content_menu_item">
<a href="#">Im a menu item</a>
<ul>
<li>
<a href="#">Sub Item 1</a>
</li>
<li>
<a href="#">Sub Item 2</a>
</li>
<li>
<a href="#">Sub Item 3</a>
</li>
</ul>
</div><div class="content_menu_item">
<a href="#">Im a menu item</a>
<ul>
<li>
<a href="#">Sub Item 1</a>
</li>
<li>
<a href="#">Sub Item 2</a>
</li>
<li>
<a href="#">Sub Item 3</a>
</li>
</ul>
</div>
CSS的
.content_menu_item{
vertical-align: top;
display:inline-block;
width: 140px;
height: 32px;
position:relative;
border:1px solid #b388ff;
text-align: center;
background-color: #6200ea;
}
.content_menu_item a{
line-height: 32px;
display: inline-block;
text-decoration: none;
color:white;
width: 140px;
}
ul{
padding: 0;
list-style:none;
display:none;
margin: 0;
opacity:0.5;
}
.content_menu_item ul li{
color:white;
background: #1e88e5;
line-height: 26px;
vertical-align: top;
transition:all 385ms cubic-bezier(0.895, 0.03, 0.685, 0.22);
opacity:0;
}
.content_menu_item ul li.on{
opacity:1;
}
.content_menu_item ul li.on:nth-child(1){
transition-delay:0ms;
}
.content_menu_item ul li.on:nth-child(2){
transition-delay:50ms;
}
.content_menu_item ul li.on:nth-child(3){
transition-delay:100ms;
}
.content_menu_item ul li.off{
opacity:0;
}
.content_menu_item ul li.off:nth-child(3){
transition-delay:0ms;
}
.content_menu_item ul li.off:nth-child(2){
transition-delay:50ms;
}
.content_menu_item ul li.off:nth-child(1){
transition-delay:100ms;
}
j查询鼠标的状态
$('.content_menu_item').hover(
function(){
// mouse over
$(this).find('ul').show(); // show the sub list of the menu, basicaly display block
timmeron = setTimeout(()=>{ // 10 miliseconds later add the class to change the opacity, the on class has a transition-delay for every element usin nth-child
$(this).find('li').addClass('on');
},10);
},function(){
//mouse out
$(this).find('li').removeClass('on'); // remove the on class
$(this).find('li').addClass('off'); // add the off class to invert the transition-delay
timmeroff = setTimeout(()=>{
$(this).find('ul').hide(); // hide the element with time after the transition completes
$(this).find('li').removeClass('off'); // remove both classes
$(this).find('li').removeClass('on');
},500);
})
这是一个工作示例https://codepen.io/Teobis/pen/QxmqGQ
希望这有帮助
@rodneyrehm的答案几乎总结了使用css显示属性处理动画时所需的一切。
您需要在切换显示属性后触发重排,并在它之后应用动画类。
// find elements
const banner = $("#banner")
const button = $(".banner__button")
const text = $(".banner__text")
let isVisible = false
// toggle display
button.on("click", () => {
if (!isVisible) {
text.addClass("display--block")
text.outerWidth()
text.addClass("text--show")
isVisible = true
} else {
text.addClass("text--hide")
.one('webkitAnimationEnd oanimationend msAnimationEnd animationend', () => {
text.removeClass("display--block")
text.removeClass("text--show")
text.removeClass("text--hide")
isVisible = false
})
}
})
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#banner {
background: #fff;
border-radius: 4px;
padding: 20px;
font-size: 25px;
text-align: center;
margin: 0 auto;
width: 300px;
height: 150px;
display: flex;
flex-flow: column nowrap;
}
.banner__button {
background: #0084ff;
border: none;
border-radius: 5px;
padding: 8px 14px;
font-size: 15px;
color: #fff;
cursor: pointer;
transition: box-shadow 0.3s, transform 0.6s;
}
.banner__button:hover {
box-shadow: 0 3px 8px 2px #9d9d91;
transform: translateY(-2px)
}
.banner__button:focus {
outline: 0;
}
.flex--1 {
flex: 1;
}
.banner__text {
display: none;
opacity: 0;
transition: all 0.6s;
}
.display--block {
display: block;
}
.text--show {
animation: slide-in 1s forwards;
}
.text--hide {
animation: slide-out 1s forwards;
}
@keyframes slide-in {
0% {
opacity: 0;
transform: translateX(-30px)
}
100% {
opacity: 1;
transform: translateX(0px)
}
}
@keyframes slide-out {
0% {
opacity: 1;
transform: translateX(0px)
}
100% {
opacity: 0;
transform: translateX(30px)
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="banner">
<div class="flex--1">
<p class="banner__text">Hello World</p>
</div>
<button class="banner__button">Toggle Text</button>
</div>
如果可能的话,用div 包裹父级。然后那个div woud 是你的不透明度过渡和你的原始父级一个显示没有
<div class="wrapper">
<div class="parent">
<div class="child">Content</div>
</div>
</div>
.wrapper{ opacity: 0; transition: all 0.5s; }
.parent{ display: none; }
.wrapper:hover{ opacity: 1;}
.parent{ display: block; }