How to Listen for CSS Transition End Events in jQuery
Listening for CSS transition end events in jQuery allows you to
execute JavaScript callbacks immediately after a CSS animation finishes.
This guide covers how to bind the standard transitionend
event using jQuery's .on() and .one() methods,
how to handle cross-browser vendor prefixes, and how to prevent callback
issues caused by multiple transitioned properties.
The Basic Syntax
Modern browsers support the standard transitionend
event. You can attach a listener to an element using jQuery's
.on() method:
$('#myElement').on('transitionend', function(e) {
console.log('Transition completed!');
});Cross-Browser Support
To support older browsers that rely on vendor prefixes, list all variations separated by spaces within the event listener:
$('#myElement').on('transitionend webkitTransitionEnd oTransitionEnd', function() {
$(this).addClass('active');
});jQuery will automatically bind to whichever event the browser fires.
Firing the Callback Only
Once with .one()
If an element transitions multiple CSS properties (such as
opacity, transform, and width),
the transitionend event fires once for every property that
finishes. If you only want your callback to run once for the entire
transition sequence, use .one() instead of
.on():
$('#myElement').one('transitionend webkitTransitionEnd oTransitionEnd', function() {
console.log('Fired only once, even if multiple properties transitioned.');
});Filtering Specific CSS Properties
If an element has multiple transitions and you need to respond to a
specific property's completion, inspect the propertyName on
the original event object:
$('#myElement').on('transitionend', function(e) {
if (e.originalEvent.propertyName === 'opacity') {
console.log('Opacity transition finished.');
}
});Handling Event Bubbling
The transitionend event bubbles up the DOM tree. If a
child element finishes a transition, the parent element will also
receive the event. To ensure the event originated from the intended
element, verify the event target:
$('#parentContainer').on('transitionend', function(e) {
if (e.target === this) {
console.log('Parent transition completed, ignoring child transitions.');
}
});