当父级从显示:无到阻止时如何转换子项



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

相关内容

  • 没有找到相关文章

最新更新