【问题标题】:Possible to reverse a css animation on class removal?可以在删除类时反转css动画吗?
【发布时间】:2013-08-04 03:14:49
【问题描述】:

基本上我要做的是在一个元素获得一个类时给它一个 CSS 动画,然后在我删除该类时反转该动画在 DOM 呈现时不播放动画

在这里提琴:http://jsfiddle.net/bmh5g/

正如您在小提琴中看到的那样,当您将鼠标悬停在“悬停我”按钮时,#item 会向下翻转。当您将鼠标悬停在悬停按钮上时,#item 就会消失。我希望#item 向上翻转(理想情况下使用相同的动画但相反)。这可能吗?

$('#trigger').on({
  mouseenter: function() {
    $('#item').addClass('flipped');
  },
  mouseleave: function() {
    $('#item').removeClass('flipped');
  }
})
#item {
  position: relative;
  height: 100px;
  width: 100px;
  background: red;
  -webkit-transform: perspective(350px) rotateX(-90deg);
  transform: perspective(350px) rotateX(-90deg);
  -webkit-transform-origin: 50% 0%;
  transform-origin: 50% 0%;
}

#item.flipped {
  animation: flipper 0.7s;
  animation-fill-mode: forwards;
  -webkit-animation: flipper 0.7s;
  -webkit-animation-fill-mode: forwards;
}

@keyframes flipper {
  0% {
    transform: perspective(350px) rotateX(-90deg);
  }
  33% {
    transform: perspective(350px) rotateX(0deg);
  }
  66% {
    transform: perspective(350px) rotateX(10deg);
  }
  100% {
    transform: perspective(350px) rotateX(0deg);
  }
}

@-webkit-keyframes flipper {
  0% {
    -webkit-transform: perspective(350px) rotateX(-90deg);
  }
  33% {
    -webkit-transform: perspective(350px) rotateX(0deg);
  }
  66% {
    -webkit-transform: perspective(350px) rotateX(10deg);
  }
  100% {
    -webkit-transform: perspective(350px) rotateX(0deg);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='trigger'>Hover Me</div>
<div id='item'></div>

【问题讨论】:

    标签: javascript jquery html css


    【解决方案1】:

    我会让#item 在默认情况下以反向动画隐藏。然后添加类以赋予它动画并显示#itemhttp://jsfiddle.net/bmh5g/12/

    $('#trigger').on({
      mouseenter: function() {
        $('#item').show();
        $('#item').addClass('flipped');
      },
      mouseleave: function() {
        $('#item').removeClass('flipped');
      }
    });
    #trigger {
      position: relative;
      display: inline-block;
      padding: 5px 10px;
      margin: 0 0 10px 0;
      background: teal;
      color: white;
      font-family: sans-serif;
    }
    
    #item {
      position: relative;
      height: 100px;
      width: 100px;
      background: red;
      display: none;
      -webkit-transform: perspective(350px) rotateX(-90deg);
      transform: perspective(350px) rotateX(-90deg);
      -webkit-transform-origin: 50% 0%;
      transform-origin: 50% 0%;
      animation: flipperUp 0.7s;
      animation-fill-mode: forwards;
      -webkit-animation: flipperUp 0.7s;
      -webkit-animation-fill-mode: forwards;
    }
    
    #item.flipped {
      animation: flipper 0.7s;
      animation-fill-mode: forwards;
      -webkit-animation: flipper 0.7s;
      -webkit-animation-fill-mode: forwards;
    }
    
    @keyframes flipper {
      0% {
        transform: perspective(350px) rotateX(-90deg);
      }
      33% {
        transform: perspective(350px) rotateX(0deg);
      }
      66% {
        transform: perspective(350px) rotateX(10deg);
      }
      100% {
        transform: perspective(350px) rotateX(0deg);
      }
    }
    
    @-webkit-keyframes flipper {
      0% {
        -webkit-transform: perspective(350px) rotateX(-90deg);
      }
      33% {
        -webkit-transform: perspective(350px) rotateX(0deg);
      }
      66% {
        -webkit-transform: perspective(350px) rotateX(10deg);
      }
      100% {
        -webkit-transform: perspective(350px) rotateX(0deg);
      }
    }
    
    @keyframes flipperUp {
      0% {
        transform: perspective(350px) rotateX(0deg);
      }
      33% {
        transform: perspective(350px) rotateX(10deg);
      }
      66% {
        transform: perspective(350px) rotateX(0deg);
      }
      100% {
        transform: perspective(350px) rotateX(-90deg);
      }
    }
    
    @-webkit-keyframes flipperUp {
      0% {
        -webkit-transform: perspective(350px) rotateX(0deg);
      }
      33% {
        -webkit-transform: perspective(350px) rotateX(10deg);
      }
      66% {
        -webkit-transform: perspective(350px) rotateX(0deg);
      }
      100% {
        -webkit-transform: perspective(350px) rotateX(-90deg);
      }
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <div id='trigger'>Hover Me</div>
    <div id='item'></div>

    【讨论】:

    • 迄今为止的最佳答案 - 我认为不可能做我想做的事。
    【解决方案2】:

    另一种方法,而不是使用display: none,是在页面加载时使用一个类来抑制反向动画,然后使用应用正常动画的相同事件删除该类(例如:flipper)。像这样(http://jsfiddle.net/astrotim/d7omcbrz/1/):

    CSS - 除了上面 Blake 发布的 FlipperUp 关键帧

    #item.no-animation 
    {
      animation: none;
    }
    

    jQuery

    $('#trigger').on({
        mouseenter: function(){
            $('#item').removeClass('no-animation');
            $('#item').addClass('flipped');
        },
        mouseleave: function(){
            $('#item').removeClass('flipped');
        }
    })
    

    【讨论】:

    • #item 应该一直显示时的好解决方案,但仅在某些事件之后才显示动画,例如:hover.
    【解决方案3】:

    除了这里的答案,请缓存你的$(selector)

    所以你几乎可以这样做var elements = $(selector); 来缓存。

    为什么?!因为如果您按原样使用此页面答案中的代码,您每次都会向 DOM 询问相同的元素集合 ($('#item'))。 DOM 读取是一项昂贵的操作。

    例如,接受的答案如下所示:

    var item = $('#item');
    $('#trigger').on({
        mouseenter: function(){
            item.show();
            item.addClass('flipped');
        },
        mouseleave: function(){
            item.removeClass('flipped');
        }
    });
    

    既然我已经写了所有这些文字,不妨使用 CSS 过渡回答你的问题

    我知道你要求一个 CSS 动画示例,但是对于你想做的动画(一张卡片翻转打开),可以使用 CSS 过渡轻松实现:

    #item {
      width: 70px;
      height: 70px;
      background-color: black;
      line-height: 1;
      color: white;
    }
    
    #item+div {
      width: 70px;
      height: 100px;
      background-color: blue;
      transform: perspective(250px) rotateX(-90deg);
      transform-origin: 50% 0%;
      transition: transform .25s ease-in-out
    }
    
    #item:hover+div {
      transform: perspective(250px) rotateX(0);
    }
    <div id="item"></div>
    <div></div>

    【讨论】:

    • 真正的快人,如果您不喜欢答案,请在下面留言说明原因,当您在答案中获得 +4 并且无缘无故弹出 -1 时,这确实令人困惑.
    • 这是迄今为止更好的解决方案 imo ?
    【解决方案4】:

    它使用 css 动画下来,所以要让它动画起来,你需要创建一个类,比如 .item-up ,它会进行相反的转换,然后你会删除前一个类并添加 item-up 类和这应该让它动起来。

    我会为它写一个 js fiddle,但我不太了解语法。

    基本上什么时候需要:

    @keyframes flipper
    @keyframes flipper-up  //This does the opposite of flipper
    

    $('#trigger').on({
        mouseenter: function(){
            $('#item').removeClass('flipped-up');
            $('#item').addClass('flipped');
        },
        mouseleave: function(){
            $('#item').removeClass('flipped');
            $('#item').addClass('flipped-up');
        }
    })
    

    jsfiddle.net/bmh5g/3 由杰克提供

    【讨论】:

    • 我看到这个方法的问题是,我不喜欢同时拥有两个类的元素的不可预测性。如果我将鼠标放在元素上,然后在它完成之前鼠标关闭会发生什么?
    • Fiddle: jsfiddle.net/bmh5g/3 这工作得很好,除了如果你不断地悬停,它就会消失。
    • 感谢 jsfiddle。
    • 我觉得这个问题的有趣之处在于是否有一种方法可以做到这一点,而无需简单地制作另一个课程。
    • 我不认为你可以用关键帧,但没有关键帧它工作得很好,但你不能得到你用关键帧得到的动画 -> jsfiddle.net/bmh5g/10
    【解决方案5】:

    您可以使用属性animation-direction 反向运行相同的动画。 如果您将此与here 中描述的用于重新启动动画的众多方法之一结合使用,我们可以在mouseenter 上开始动画正向播放,然后在mouseleave 上我们可以重新启动它并反向播放。

    我不太会用jQuery,所以选择了文章中提到的非jQuery方法之一。

    const element_button = document.getElementById('trigger');
    const element_item = document.getElementById('item');
    
    element_button.addEventListener("mouseenter", () => {
      if (element_item.classList.contains('animate-backwards')) {
        element_item.classList.remove('animate-backwards');
        void element_item.offsetWidth;
      }
      
      element_item.classList.add('animate-forwards');
    });
    
    element_button.addEventListener("mouseleave", () => {
      element_item.classList.remove('animate-forwards');
      void element_item.offsetWidth;
      
      element_item.classList.add('animate-backwards');
    });
    

    #item.animate-forwards {
      animation: flipper 0.7s normal;
      -webkit-animation: flipper 0.7s normal;
      
      animation-fill-mode: forwards;
      -webkit-animation-fill-mode: forwards;
    }
    
    #item.animate-backwards {
      animation: flipper 0.7s reverse;
      -webkit-animation: flipper 0.7s reverse;
      
      animation-fill-mode: forwards;
      -webkit-animation-fill-mode: forwards;
    }
    

    这是上面代码的jsFiddle

    【讨论】:

      【解决方案6】:

      来自MDN 的 CSS 解决方案,几乎所有浏览器都支持

      .animation(animationName 10s ease-in-out 无限交替同时运行;)

      【讨论】:

        【解决方案7】:

        为我工作: 元素的 1 个反向动画(从 100% 到 0%) 1 个新类的单独动画转发(从 0% 到 100%) 并且切换该类将起作用

          [1]: https://jsfiddle.net/q7bc4s0f/17/
        

        更新: 这样动画将在页面加载时向后播放。要解决这个问题,您必须在事件 ONCE 上添加新的 bacwards 动画类,然后在该事件上切换前向动画类。

        【讨论】:

        • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
        猜你喜欢
        • 2021-09-21
        • 1970-01-01
        • 1970-01-01
        • 2015-09-01
        • 1970-01-01
        • 2020-08-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多