如何将jQuery动画反转回原始CSS属性

时间:2022-11-05 20:32:22

There are a lot of very similar questions on here but I cannot find an exact answer to my question.

这里有很多非常相似的问题,但我无法找到问题的确切答案。

I am new to using the jQuery .animate() method and I want to know if there's a common or best method of reversing the animation?

我是新手使用jQuery .animate()方法,我想知道是否有一种通用或最好的方法来反转动画?

Here is a fiddle for an example of what I've come up with: Fiddle

这是一个关于我想出的例子的小提琴:小提琴

Essentially all it does is use an if statement to check one CSS property and then animate it to one state or back to the other state.

基本上它所做的就是使用if语句检查一个CSS属性,然后将其设置为一个状态或返回另一个状态。

$(document).ready(function () {
    $("[name=toggle]").on("click", function () {
        if ($('.box').width() < 125) {
            $(".box").animate({
                opacity: .3,
                width: "125px",
                height: "125px"
            }, 250);
        } else {
            $(".box").animate({
                opacity: 1,
                width: "100px",
                height: "100px"
            }, 250)
        }
    });
});
.box {
    background-color: lightblue;
    box-shadow: 5px 5px 10px #000000;
    width: 100px;
    height: 100px;
    display: block;
    margin: 20px auto 0 auto;
    border-radius: 25px;
}
[name="toggle"] {
    display: block;
    margin: 0 auto;
    margin-top: 15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<button name="toggle">Animate</button>
<div class="box"></div>

This is what I was able to come up with with my first exposure to .animate(), but I think there may be a better way. Say you want to have an animation on hover, and reverse the animation when the mouse is moved off the element. Is there a way to easily reverse the jQuery animation easily? I am away I could use a :hover state with CSS, but this is a hypothetical question regarding jQuery .animate().

这是我第一次接触.animate()时能够想到的,但我认为可能有更好的方法。假设您希望在悬停时生成动画,并在将鼠标移离元素时反转动画。有没有办法轻松地轻松扭转jQuery动画?我离开了我可以使用:使用CSS的悬停状态,但这是一个关于jQuery .animate()的假设问题。

4 个解决方案

#1


3  

You can do that with plain CSS using transitions.

您可以使用转换使用纯CSS执行此操作。

.animate-me {
    background-color:red;
    width:50px;
    height:50px;
    position:absolute;
    top:0;
    left:150px;
    transition:left 2s, background-color 2s;
  
}  
.animate-me:hover{
  left:0;
  background-color:blue;
}
<div class="animate-me"></div>

Usually css is simpler. However when browsers are old jquery might be your only way so I have included the JQuery way.

通常css更简单。但是当浏览器很旧时,jquery可能是你唯一的方式,所以我已经包含了JQuery方式。

function animationForward(){
  $(".animate-me").animate(
  {
    opacity: 0.25,
    left: "100",
    height: "100"
  }, 5000, function() {
    animationBackward();
  }
)}
function animationBackward(){
  $(".animate-me").animate(
  {
    opacity: 1,
    left: "50",
    height: "50"
  }, 5000, function() {
    animationForward();
  }
)}
animationForward();
.animate-me {
  width:50px;
  height:50px;
  background-color:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="animate-me"></div>

#2


2  

This is probably the shortest way I can think of :

这可能是我能想到的最短路:

$(function() {

var small = true;

$('[name=toggle]').click(function() {

  small = !small;

  if (small) var properties = {opacity: 1, width: 100, height: 100};
  else properties = {opacity: .3, width: 125, height: 125};

  $('.box').stop().animate(properties, 250);
});
});
.box {
  background-color: lightblue;
  box-shadow: 5px 5px 10px #000000;
  width: 100px;
  height: 100px;
  display: block;
  margin: 20px auto 0 auto;
  border-radius: 25px;
}

[name="toggle"] {
  display: block;
  margin: 0 auto;
  margin-top: 15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button name="toggle">Animate</button>
<div class="box"></div>

Note that it's a good idea to add a .stop() to the animation. It will not get interrupted otherwise but will start accumulating the clicks (animation queue buildup) instead. More noticeable with longer durations.

请注意,向动画添加.stop()是个好主意。否则它不会被中断,但会开始累积点击次数(动画队列累积)。持续时间较长时更明显。

Here's one with hover action :

这是一个悬停动作:

$(function() {

$('[name=toggle]').on('mouseenter mouseleave', function(e) {

  if (e.type == 'mouseenter') var properties = {opacity: .3, width: 125, height: 125};
  else properties = {opacity: 1, width: 100, height: 100};

  $('.box').stop().animate(properties, 250);
});
});
.box {
  background-color: lightblue;
  box-shadow: 5px 5px 10px #000000;
  width: 100px;
  height: 100px;
  display: block;
  margin: 20px auto 0 auto;
  border-radius: 25px;
}

[name="toggle"] {
  display: block;
  margin: 0 auto;
  margin-top: 15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button name="toggle">Animate</button>
<div class="box"></div>

#3


1  

I would combine CSS transitions and using jQuery to toggle classes, like this:

我会结合CSS转换和使用jQuery来切换类,如下所示:

JSFiddle

$(document).ready(function () {
    $("[name=toggle]").on("click", function () {
        $(".box").toggleClass("differentSizeBox");
    });
});

CSS:

.box {
    background-color: lightblue;
    box-shadow: 5px 5px 10px #000000;
    width: 100px;
    height: 100px;
    display: block;
    margin: 20px auto 0 auto;
    border-radius: 25px;
    -webkit-transition: all 0.25s ease-in;
    -moz-transition: all 0.25s ease-in;
    -o-transition: all 0.25s ease-in;
    transition: all 0.25s ease-in;
}
.differentSizeBox {
    opacity: .3;
    width: 125px;
    height: 125px;
}
[name="toggle"] {
    display: block;
    margin: 0 auto;
    margin-top: 15px;
}

This way you can still control the change with a button click (or other JS events).

这样,您仍然可以通过单击按钮(或其他JS事件)来控制更改。

=====

EDIT: The only way I could think of to "reverse" with just JS changes would be to "remember" the CSS properties you are changing... and then revert back to that. This would be good in that if your original .box css changes, it would still work without changing the JS

编辑:我唯一能想到用JS改变来“逆转”的方法就是“记住”你正在改变的CSS属性......然后再回到那个。如果您的原始.box css发生更改,那么这将是很好的,但如果不更改JS,它仍然可以正常工作

JSFiddle

$(document).ready(function () {
    $boxes = $(".box");
    var boxCss = {
        opacity: $boxes.css("opacity"),
        width: $boxes.css("width"),
        height: $boxes.css("height")
    };
    $("[name=toggle]").on("click", function () {
        if ($boxes.hasClass("changed")) {
            $boxes.animate(boxCss, 250);
            $boxes.removeClass("changed");
        } else {
            $boxes.animate({
                opacity: .3,
                width: "125px",
                height: "125px"
            }, 250);
            $boxes.addClass("changed");
        }
    });
});

======

NOTE: jQueryUI has a toggleClass() that includes animations.

注意:jQueryUI有一个包含动画的toggleClass()。

#4


0  

A very naive solution, I used recently, is to get all values for the animated properties with jQuery.fn.css(arrayOfPropertyNames) and cache them with jQuery.fn.data. Then just reuse them later to revert the animation.

我最近使用的一个非常天真的解决方案是使用jQuery.fn.css(arrayOfPropertyNames)获取动画属性的所有值,并使用jQuery.fn.data缓存它们。然后稍后重复使用它们以恢复动画。

$.fn.etamina = function(values) {
  var keys = Object.keys(values)
  var args = arguments
  return this.each(function() {
    var $this = $(this)
    $.extend(values, $this.data('etamina'))
    $this.data('etamina', $this.css(keys))
    $.fn.animate.apply($this, args)
  })
}

It takes the same arguments as jQuery.fn.animate.

它采用与jQuery.fn.animate相同的参数。

  • Called the first time: it stores the original values and animates the element to the passed properties.

    第一次调用:它存储原始值并将元素设置为传递的属性的动画。

  • Second time called: it stores the animated values and animates the element to the stored original values

    第二次调用:它存储动画值并将元素设置为存储的原始值

https://jsfiddle.net/jat8wdky/

Update

You could go crazy and override the original jQuery.fn.animate to cache the values:

您可能会疯狂并覆盖原始的jQuery.fn.animate来缓存值:

var $animate = $.fn.animate
$.fn.animate = function(prop, speed, easing, callback) {
  if (!this.data('etamina')) {
    this.data('etamina', this.css(Object.keys(prop)))
  }
  return $animate.call(this, prop, speed, easing, callback)
}

$.fn.etamina = function(speed, easing, callback) {
  var prop = this.data('etamina')
  if (prop == null) {
    return this
  }
  this.data('etamina', null)
  return $animate.call(this, prop, speed, easing, callback)
}

Animate as usual with $(selector).animate, revert with $(selector).etamina.

像往常一样使用$(selector).animate进行动画处理,使用$(selector).etamina进行恢复。

// Animate
$('.foo').animate({
  top: '50%',
  left: '50%',
  width: '4em',
  height: '4em',
  marginTop: '-2em',
  marginLeft: '-2em',
  borderRadius: '50%'
})

// Revert
$('.foo').etamina()

https://fiddle.jshell.net/mk5zc1oh/

Note, that jQuery.css doesn't return the actual element offset and size, just the computed styles.

注意,jQuery.css不返回实际的元素偏移量和大小,只返回计算出的样式。

#1


3  

You can do that with plain CSS using transitions.

您可以使用转换使用纯CSS执行此操作。

.animate-me {
    background-color:red;
    width:50px;
    height:50px;
    position:absolute;
    top:0;
    left:150px;
    transition:left 2s, background-color 2s;
  
}  
.animate-me:hover{
  left:0;
  background-color:blue;
}
<div class="animate-me"></div>

Usually css is simpler. However when browsers are old jquery might be your only way so I have included the JQuery way.

通常css更简单。但是当浏览器很旧时,jquery可能是你唯一的方式,所以我已经包含了JQuery方式。

function animationForward(){
  $(".animate-me").animate(
  {
    opacity: 0.25,
    left: "100",
    height: "100"
  }, 5000, function() {
    animationBackward();
  }
)}
function animationBackward(){
  $(".animate-me").animate(
  {
    opacity: 1,
    left: "50",
    height: "50"
  }, 5000, function() {
    animationForward();
  }
)}
animationForward();
.animate-me {
  width:50px;
  height:50px;
  background-color:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="animate-me"></div>

#2


2  

This is probably the shortest way I can think of :

这可能是我能想到的最短路:

$(function() {

var small = true;

$('[name=toggle]').click(function() {

  small = !small;

  if (small) var properties = {opacity: 1, width: 100, height: 100};
  else properties = {opacity: .3, width: 125, height: 125};

  $('.box').stop().animate(properties, 250);
});
});
.box {
  background-color: lightblue;
  box-shadow: 5px 5px 10px #000000;
  width: 100px;
  height: 100px;
  display: block;
  margin: 20px auto 0 auto;
  border-radius: 25px;
}

[name="toggle"] {
  display: block;
  margin: 0 auto;
  margin-top: 15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button name="toggle">Animate</button>
<div class="box"></div>

Note that it's a good idea to add a .stop() to the animation. It will not get interrupted otherwise but will start accumulating the clicks (animation queue buildup) instead. More noticeable with longer durations.

请注意,向动画添加.stop()是个好主意。否则它不会被中断,但会开始累积点击次数(动画队列累积)。持续时间较长时更明显。

Here's one with hover action :

这是一个悬停动作:

$(function() {

$('[name=toggle]').on('mouseenter mouseleave', function(e) {

  if (e.type == 'mouseenter') var properties = {opacity: .3, width: 125, height: 125};
  else properties = {opacity: 1, width: 100, height: 100};

  $('.box').stop().animate(properties, 250);
});
});
.box {
  background-color: lightblue;
  box-shadow: 5px 5px 10px #000000;
  width: 100px;
  height: 100px;
  display: block;
  margin: 20px auto 0 auto;
  border-radius: 25px;
}

[name="toggle"] {
  display: block;
  margin: 0 auto;
  margin-top: 15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button name="toggle">Animate</button>
<div class="box"></div>

#3


1  

I would combine CSS transitions and using jQuery to toggle classes, like this:

我会结合CSS转换和使用jQuery来切换类,如下所示:

JSFiddle

$(document).ready(function () {
    $("[name=toggle]").on("click", function () {
        $(".box").toggleClass("differentSizeBox");
    });
});

CSS:

.box {
    background-color: lightblue;
    box-shadow: 5px 5px 10px #000000;
    width: 100px;
    height: 100px;
    display: block;
    margin: 20px auto 0 auto;
    border-radius: 25px;
    -webkit-transition: all 0.25s ease-in;
    -moz-transition: all 0.25s ease-in;
    -o-transition: all 0.25s ease-in;
    transition: all 0.25s ease-in;
}
.differentSizeBox {
    opacity: .3;
    width: 125px;
    height: 125px;
}
[name="toggle"] {
    display: block;
    margin: 0 auto;
    margin-top: 15px;
}

This way you can still control the change with a button click (or other JS events).

这样,您仍然可以通过单击按钮(或其他JS事件)来控制更改。

=====

EDIT: The only way I could think of to "reverse" with just JS changes would be to "remember" the CSS properties you are changing... and then revert back to that. This would be good in that if your original .box css changes, it would still work without changing the JS

编辑:我唯一能想到用JS改变来“逆转”的方法就是“记住”你正在改变的CSS属性......然后再回到那个。如果您的原始.box css发生更改,那么这将是很好的,但如果不更改JS,它仍然可以正常工作

JSFiddle

$(document).ready(function () {
    $boxes = $(".box");
    var boxCss = {
        opacity: $boxes.css("opacity"),
        width: $boxes.css("width"),
        height: $boxes.css("height")
    };
    $("[name=toggle]").on("click", function () {
        if ($boxes.hasClass("changed")) {
            $boxes.animate(boxCss, 250);
            $boxes.removeClass("changed");
        } else {
            $boxes.animate({
                opacity: .3,
                width: "125px",
                height: "125px"
            }, 250);
            $boxes.addClass("changed");
        }
    });
});

======

NOTE: jQueryUI has a toggleClass() that includes animations.

注意:jQueryUI有一个包含动画的toggleClass()。

#4


0  

A very naive solution, I used recently, is to get all values for the animated properties with jQuery.fn.css(arrayOfPropertyNames) and cache them with jQuery.fn.data. Then just reuse them later to revert the animation.

我最近使用的一个非常天真的解决方案是使用jQuery.fn.css(arrayOfPropertyNames)获取动画属性的所有值,并使用jQuery.fn.data缓存它们。然后稍后重复使用它们以恢复动画。

$.fn.etamina = function(values) {
  var keys = Object.keys(values)
  var args = arguments
  return this.each(function() {
    var $this = $(this)
    $.extend(values, $this.data('etamina'))
    $this.data('etamina', $this.css(keys))
    $.fn.animate.apply($this, args)
  })
}

It takes the same arguments as jQuery.fn.animate.

它采用与jQuery.fn.animate相同的参数。

  • Called the first time: it stores the original values and animates the element to the passed properties.

    第一次调用:它存储原始值并将元素设置为传递的属性的动画。

  • Second time called: it stores the animated values and animates the element to the stored original values

    第二次调用:它存储动画值并将元素设置为存储的原始值

https://jsfiddle.net/jat8wdky/

Update

You could go crazy and override the original jQuery.fn.animate to cache the values:

您可能会疯狂并覆盖原始的jQuery.fn.animate来缓存值:

var $animate = $.fn.animate
$.fn.animate = function(prop, speed, easing, callback) {
  if (!this.data('etamina')) {
    this.data('etamina', this.css(Object.keys(prop)))
  }
  return $animate.call(this, prop, speed, easing, callback)
}

$.fn.etamina = function(speed, easing, callback) {
  var prop = this.data('etamina')
  if (prop == null) {
    return this
  }
  this.data('etamina', null)
  return $animate.call(this, prop, speed, easing, callback)
}

Animate as usual with $(selector).animate, revert with $(selector).etamina.

像往常一样使用$(selector).animate进行动画处理,使用$(selector).etamina进行恢复。

// Animate
$('.foo').animate({
  top: '50%',
  left: '50%',
  width: '4em',
  height: '4em',
  marginTop: '-2em',
  marginLeft: '-2em',
  borderRadius: '50%'
})

// Revert
$('.foo').etamina()

https://fiddle.jshell.net/mk5zc1oh/

Note, that jQuery.css doesn't return the actual element offset and size, just the computed styles.

注意,jQuery.css不返回实际的元素偏移量和大小,只返回计算出的样式。