我在创建具有特定效果的弹出菜单时遇到问题。弹出窗口从display:none到block然后我使用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;
}
答案 0 :(得分:10)
有解决方法吗?我知道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
,就会在转换时遇到困难。最好的方法是避免它。我一直在使用第二个选项而没有任何重大问题。
编辑:
.animate()
也可以在CSS中完成-webkit-transition
,还要使用正确的transition
// delay increases with each column
看起来像是一种误解。选择器.columns > li:first-child
适用的所有元素将具有完全相同的延迟 - 它们不会等待前一个元素完成其转换。如果你想在CSS中定义它,你将不得不与:nth-child()或其中一个表兄弟一起玩答案 1 :(得分:4)
如果您只想更改opacity
,可以使用JQuery的FadeIn和FadeOut功能,但如果您想要更复杂的过渡,可以使用CSS3(this是一个非常好的图书馆)。
请参阅此DEMO,您可以在其中看到这两种不同的方式。
你也可以像这样在类中添加一个控件:
$("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>
答案 2 :(得分:3)
@rodneyrehm的answer几乎总结了使用css display属性处理动画时所需的一切。
您需要在切换display属性后触发重排并在其后应用动画类。
// 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>
答案 3 :(得分:3)
前段时间我遇到了同样的问题,我的解决方法很笨拙,但大多数情况下都能起作用
当您更改一个不可转换的属性(例如“显示”问题)时,它真的很快就出错了,我发现如果您使用微调器来更改不可转换的属性,并且在几毫秒后又更改了另一个可转换的属性,这种工作方式,还需要使用另一个计时器将事情倒退
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;
}
使用jQuery进行鼠标状态
$('.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
希望这会有所帮助
答案 4 :(得分:0)
如果可能,请用 div 包裹父级。 那么那个 div 将是你的不透明度过渡,而你的原始父级是一个显示无
<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; }