父进程从display:none到block时如何转换子进程

时间:2014-11-24 21:30:46

标签: jquery css jquery-animate css-transitions css-animations

我在创建具有特定效果的弹出菜单时遇到问题。弹出窗口从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;
}

5 个答案:

答案 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,就会在转换时遇到困难。最好的方法是避免它。我一直在使用第二个选项而没有任何重大问题。


在OP添加了一些演示代码后

编辑:

  • 包装器的.animate()也可以在CSS中完成
  • 不仅要使用以供应商为前缀的CSS属性-webkit-transition,还要使用正确的transition
  • // delay increases with each column看起来像是一种误解。选择器.columns > li:first-child适用的所有元素将具有完全相同的延迟 - 它们不会等待前一个元素完成其转换。如果你想在CSS中定义它,你将不得不与:nth-child()或其中一个表兄弟一起玩

答案 1 :(得分:4)

如果您只想更改opacity,可以使用JQuery的FadeInFadeOut功能,但如果您想要更复杂的过渡,可以使用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; }