可以在移除类时反转CSS动画吗?


69

本质上,我想做的就是在元素获得类后为其提供CSS动画,然后在删除类时反转该动画,而在DOM渲染时不播放该动画

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

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

HTML:

<div id='trigger'>Hover Me</div>
<div id='item'></div>

CSS:

#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); }
}

Javascript:

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

Answers:


25

#item默认情况下,我会使用反向动画隐藏开始的内容。然后添加该类以为其赋予动画并显示#itemhttp://jsfiddle.net/bmh5g/12/

jQuery的

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

的CSS

#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;
}

1
到目前为止最好的答案-我认为不可能做我想做的事。
杰克

8

除了使用之外display: none,另一种方法是使用页面加载时的类抑制反向动画,然后使用与应用常规动画相同的事件(例如,脚蹼)删除该类。像这样(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');
    }
})

1
一个好的解决方案,#item应该始终显示何时,但只能在某些事件(例如)之后进行动画处理:hover
Ilya Luzyanin

5

除了此处的答案外,请缓存您的 $(selector)

因此,您几乎可以执行此操作var elements = $(selector);以进行缓存。

为什么?!因为如果您照原样使用此页面上答案中的代码,则$('#item')每次都会向DOM请求相同的元素集合()。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>


1
真正的快手,如果您不喜欢答案,请在下面留下评论,为什么,当您在答案上获得+4且无缘无故弹出-1时,这确实非常令人困惑。
Kitanga Nday

0

它使用css进行动画处理,以便使其动画起来,您需要创建一个类,例如说.item-up,它进行相反的转换,因此您将删除上一个类并添加item-up类,并且应该对其进行动画处理起来。

我会为您编写一个js小提琴,但是我不太了解语法。

基本上,您何时需要:

@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 由Jake提供


我看到的这种方法的问题是,我不喜欢具有两个同时具有动画的类的元素的不可预测性。如果我将鼠标悬停在元素上并在完成之前将其关闭,该怎么办?
杰克

3
小提琴:jsfiddle.net/bmh5g/3 这很好用,但是如果您不断地徘徊和消失,它就会消失。
杰克

谢谢,我感谢jsfiddle。
Shane

1
我觉得使这个问题有趣的是,是否有一种方法而不必简单地开设另一个班级。
2013年

1
我认为您无法使用关键帧,但是如果没有关键帧,它就可以正常工作,但是您无法获得使用关键帧获得的动画-> jsfiddle.net/bmh5g/10
adeneo 2013年

0

您可以利用该属性animation-direction反向运行相同的动画。如果将其与此处介绍的多种重新启动动画的方法之一结合使用-我们可以在上向前启动动画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


-1

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

.animation(animationName 10s缓入无限交替运行)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.