How do I use transitionend in jQuery?

I need to detect if a CSS transition is completed before allowing a function to repeat again, to prevent messing up the margins.

So how cam I have something like

if (transitionend == true) {
  // do stuff
} else {
  // do nothing
}

Solution 1:

The code below will trigger on the transitionend event for whatever element(s) you have in the $element variable. There are four different event names as I believe these cover all of the cross-browser inconsistencies. Replace the '// your event handler' comment with whatever code you wish to run when the event is triggered.

$element.on('transitionend webkitTransitionEnd oTransitionEnd', function () {
    // your event handler
});

Solution 2:

I think this link might be helpful to you.

There is a single event that is fired when transitions complete. In Firefox, the event is transitionend, in Opera, OTransitionEnd, and in WebKit it is webkitTransitionEnd.

el.addEventListener("transitionend", updateTransition, true);

Solution 3:

Use jQuery data to attach stateful data to the element. Use a boolean value to "block" events from happening and flip the boolean variable once transitionend completes. Use xram's code to hook up all cross-browser transitionend events at the same time.

So for your example...

  1. onclick set this.data('transitioning', true)
  2. when transitionend fires, set this.data('transitioning', false)
  3. don't perform animation if this.data('transitioning') == true. this is captured and checked in your click event.

Solution 4:

You can create a method which will keep in mind when the transition end has been called the last time, and thus only trigger the callback once.

function transitionEndsOnce($dom, callback) {
  var tick = Date.now();
  $dom.on('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd', function(e) {
    var diff = Date.now() - tick;
    tick = Date.now();
    if (diff > 20) { // this number can be changed, but normally all the event trigger are done in the same time
      return callback && callback(e);
    }
  });
}

and then simply use it this way

transitionEndsOnce($('...'), function(e){
  console.log('transition ends once');
});