Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Toggle CSS transitions on and off with JavaScript

All,

I've got a situation in which I'm using CSS transforms/transitions to animate the horizontal position of a div element. Specifically, I'm using...

// in CSS
myDiv {
    transition: transform 0.4s ease-in;
}

// in JavaScript, where "div" contains a reference to the div element
div.style.transform = translate3d(Npx, 0px, 0px);

...and it works well. That is, every time I call that line of JavaScript with a new value for N, the div smoothly animates from its current position to its new position.

However, there are times when I need position the div first WITHOUT a transition, then MOVE it WITH a transition. E.g.,

  1. Have the div JUMP (instantly) to 100px, then transition (over 400ms) to 200px
  2. Later, JUMP the div to 500px (without a transition), then transition it to 600px

In other words, I'd like to be able to move a div, and be able to control whether the new position is applied instantaneously, or with a transition.

Complicating matters, I have event listeners that fire when the transition is complete; these listeners should NOT fire if/when I move the div without a transition. I'm also supporting multiple browsers, so I have to deal with all the vendor prefixes.

In pseudo-code, I guess it would look something like this:

  1. Remove the event listeners for the transitionEnd event
  2. Set the transition property to none
  3. Change the position of the div (e.g., [div].style.transform = translate3d([starting position]px, 0px, 0px))
  4. Add the event listeners for the transitionEnd event
  5. Set the transition property to have a transition (e.g., [div].style.transition:all 0.4s ease-in)
  6. Change the position of the div (e.g., [div].style.transform = translate3d([ending position]px, 0px, 0px))

With all the vendor prefixes, that's too messy and complicated to be the best way to accomplish this. (I'm not even sure if it works...)

So, what's the best way to toggle transitions/transformations on and off?

[UPDATE]

Thanks to a suggestion from Chandranshu, I've tried toggling a class that includes the transitions.

So, my pseudocode looks like this:

  1. Remove the transitions class
  2. Apply the starting position
  3. Restore the transitions class
  4. Apply the ending position

However, it looks like, if I execute all four steps in a single JavaScript function - it seems to ignore steps 1-2, as though it's "netting" the results of all four steps.

Here's a jsfiddle that demonstrates this: http://jsfiddle.net/bUvX3/

Instead - if I execute steps 1 and 2, then execute steps 3 and 4 after a short delay (e.g., by using a setTimeout), it works: http://jsfiddle.net/2mhcv/

So, I guess that's a solution, except that I really don't like having to add an arbitrary delay, especially when so much emphasis is placed on fast, responsive UIs.

Thanks in advance!

like image 667
mattstuehler Avatar asked Apr 16 '26 19:04

mattstuehler


1 Answers

I think you have over-complicated this :). Here's how I'd approach this problem:

  1. Add a class to your divs, say movable.
  2. Declare all your transition rules and transitionEnd callbacks for .movable.
  3. Nothing to do if you want to move your div smoothly.
  4. When you need to move your div w/o a transition, remove this class, move your div and add this class back: $('div').removeClass('movable').animate({transform: 'translate3d(...)' }).addClass('movable')

UPDATE:

Finally, I've got what you wanted: http://jsfiddle.net/2mhcv/1/. The only change here is that instead of a delay of 20ms, I'm using a delay of 0! setTimeout() causes a repaint to be triggered and that ensures that the first animation is executed before the next one begins.

UPDATE 2:

This version works without a setTimeout() call: http://jsfiddle.net/2mhcv/2/. Realizing that a repaint is all that is needed, I just added a line there to read a compute CSS property such as display. You could have read any other computed property to get the same effect.

like image 79
Chandranshu Avatar answered Apr 18 '26 09:04

Chandranshu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!