简体   繁体   中英

jQuery Calculating Width and Height After All Active CSS Transitions Complete

Is it possible to calculate the size of an element after an animation has complete using jQuery? My simplified example is:

<style>
  .brick
  {
    transition: all 0.4s ease-in-out;
  }
  .large
  {
    width: 400px;
    height: 400px;
  }
  .small
  {
    width: 200px;
    height: 200px;
  }
</style>

<script>
  $('.brick').removeClass('small').addClass('large');
  $('.brick').height(); // returns 200px but desired 400px
  $('.brick').width();  // returns 200px but desired 400px
</script>

I can't wait until after the animation completes to get the sizes and I can't hardcode any of the sizes in the JS. Any ideas?

Edit: Typo on sizes for small and large

You could just create an element with the same class and no transition, and get the dimensions of that element, as that would be the same as when the transition ends on the existing element :

var brick = $('<div />', {
                          'class':'brick large', 
                           style :'transition:none; left: -9999px;'
                         }
            ).appendTo('body');

var w = brick.height()
var h = brick.width();

brick.remove();

FIDDLE

You totally can, just listen to the "transitionend" event on the element. Note the name of the event is different depending on browser vendors. For a complete list look here .

UPDATE:
Okay so based on your comment I assume you want the resulted sizes right after you initiated the animation. Things to keep in mind tho is for the javascript to fetch the size of an element, the element has to already be that size.

I can think of 2 approaches as for now:

  1. Instantly apply the size change on the child container, but animate the parent container. You will know the resulted size by looking at the size of the child container. You can have overflow:hidden on the parent container to void content overflowing in process of the animation. Notice that "instantly apply size change' doesn't mean you can't apply animations at all, you can still apply animations only if they do not interfere with the size, for example, fadeIn.
  2. Construct a dummy element that's identical to the one you are interested in, remove CSS3 transitions on that element and apply the class changes, then grab the size of the dummy element.

I would just add a timeout with the set number of milliseconds for the transition.

setTimeout(function(){
    $('.brick').removeClass('small').addClass('large');
    $('.brick').height(); // returns 200px but desired 400px
    $('.brick').width();  // returns 200px but desired 400px
}, 400);

I would only do this if this is the only thing you are trying to grab. Expanding this might get difficult if there are more than one thing transforming

This answer is inspired from Adeneo's answer, but is done on the already exisitng element instead of a copy. In many cases it can be hard to make the copy to have the same content and same styling as the original element, so working on the original element is probably easier.

Here is how I modified your code example:

<style>
  .brick
  {
  }

  .transition
  {
      transition: all 0.4s ease-in-out;
  }

  .large
  {
    width: 400px;
    height: 400px;
  }

  .small
  {
    width: 200px;
    height: 200px;
  }
</style>

<div class="brick small"></div>

<script>
  $('.brick').height(); // returns 200px
  $('.brick').width();  // returns 200px

  // Apply final styling and get dimensions.
  $('.brick').removeClass('small').addClass('large');
  $('.brick').height(); // returns 400px
  $('.brick').width();  // returns 400px

  // Restore styling to what it was before measuring dimensions.
  // Note width() and/or height() must be called after restoring the
  // initial style to force layout to update. If you don't, the
  // transition won't work.
  $('.brick').addClass('small').removeClass('large');
  $('.brick').height(); // returns 200px.
  $('.brick').width();  // returns 200px.

  // Apply final styling again, but include transition.
  $('.brick').removeClass('small').addClass('large transition');
</script>

In a JS Fiddle: http://jsfiddle.net/qptwnq5p/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM