Webkit Transitionend Event Grouping

transitionend event doesn't fire when my animation finishes

You're not getting a transitionend event because you're not using CSS transitions; you're using CSS animations. The CSS of the animated and fadeOut classes in animate.css is as follows:

.animated {
-webkit-animation-duration: 1s;
-moz-animation-duration: 1s;
-o-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: both;
-moz-animation-fill-mode: both;
-o-animation-fill-mode: both;
animation-fill-mode: both;
}

.animated.fadeOut {
-webkit-animation-name: fadeOut;
-moz-animation-name: fadeOut;
-o-animation-name: fadeOut;
animation-name: fadeOut;
}

@-webkit-keyframes fadeOut {
0% {opacity: 1;}
100% {opacity: 0;}
}

@-moz-keyframes fadeOut {
0% {opacity: 1;}
100% {opacity: 0;}
}

@-o-keyframes fadeOut {
0% {opacity: 1;}
100% {opacity: 0;}
}

@keyframes fadeOut {
0% {opacity: 1;}
100% {opacity: 0;}
}

.animated.fadeOut {
-webkit-animation-name: fadeOut;
-moz-animation-name: fadeOut;
-o-animation-name: fadeOut;
animation-name: fadeOut;
}

That's not a CSS transition, it's a CSS animation. They trigger different events on completion.

Replace this:

$(this).on('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend',

with this:

$(this).on('webkitAnimationEnd oanimationend oAnimationEnd msAnimationEnd animationend',

and I think everything should work fine.

The fact that something was happening when you moused off the $(this) element is, I suspect, a coincidence; perhaps you have an entirely separate handler, like a mouseout handler, with similar behavior that you're mistaking for the transitionend handler, or perhaps you have some CSS transitions being applied on hover and one of those is triggering a transitionend event completely unrelated to the fadeOut?

Why is my transitionend event triggering immideately?

mh...

// active elements needs to transition out
activeElement
.addClass(transition + " out")
.on( self._transitionEndEvents, complete(activeElement, true) );

// element clicked contains a reference to the element
// that should be the new active element
e.target.reference
.addClass(transition + " in ui-carousel-active DUMB")
.on( self._transitionEndEvents, complete(e.target.reference) );

The problem is adding a class of "transition" (e.g. slide) and in will trigger a transition BEFORE setting the listener for it. That's why it did not work.

Simply changing order to first listening and then triggering:

// active elements needs to transition out
activeElement
.on( self._transitionEndEvents, complete(activeElement, true) )
.addClass(transition + " out");

// element clicked contains a reference to the element
// that should be the new active element
e.target.reference
.on( self._transitionEndEvents, complete(e.target.reference) )
.addClass(transition + " in ui-carousel-active");

fixes it and I can remove the setTimeout call.

How do I detect a transition end without a JavaScript library?

element.addEventListener('transitionend', function(event) {
alert("CSS Property completed: " + event.propertyName);
}, false );

For now, the exact event name has not been standardized. Here's a quote from MDN:

There is a single event that is fired when transitions complete.

In all standard-compliant browser, the event is transitionend,

in WebKit it is webkitTransitionEnd.

Here's the fiddle for Webkit: http://jsfiddle.net/bNgWY/

Firing event listeners inside a transitionend event listener?

Here's something which will work once per transition:

var transitioned = document.getElementById("transition");var show = document.getElementById("show");var hasEnded = false;
transitioned.addEventListener("transitionend", function(evt){ console.log("end") hasEnded = true;});
transitioned.addEventListener("mousemove", function(evt){ if(hasEnded) { console.log("Mousemoving"); }});
#transition {  background: yellow;  padding: 10px;  transition: all 1s linear;    -webkit-transition: all 1s linear;}#transition:hover {  background: red;}
<div id="transition">Hover me!</div>

Why is the transitionend event firing before the transition completes?

Edit:

After having a look at your fiddle, I found several issues with your code.

  1. The reason your reset is firing immediately (The topic my original answer dealt with) is that you are calling it instead of adding it as an event listener.

  2. You call show before the transition ends, and so when calling reset, the fadein class is removed and the new page is hidden.

I have forked your fiddle with some changes to make it work.


For completeness, my original answer:

You have a mistake in your hide(id) function

You are calling reset immediately. Change reset(page) to reset.bind(null, page):

function hide(id) {
page = document.getElementById(id);
page.addEventListener('transitionend', *reset(page)*, false);
page.classList.add('fadeOut');
page.removeEventListener('transitionend', *reset(page)*, false);
}

To

function hide(id) {
page = document.getElementById(id);
page.addEventListener('transitionend', reset.bind(null, page), false);
page.classList.add('fadeOut');
page.removeEventListener('transitionend', reset.bind(null, page), false);
}

Where to put callback function in react-transition-group

You can use addEndListener, or even onExited and onEntered callbacks.

With addEndListener:

function abc() {
// blah
// blah
//blah
}

... // some code

<Transition
addEndListener={(node, done) => {node.addEventListener('transitionend',(e) => {
abc(e);
done(e);
}, false);}}>
<MyComponent />
</Transition>

With onEntered and onExited:

<Transition
onEntered={abc} onExited={abc}>
<MyComponent />
</Transition>

An important thing of the second example: check the moment, when you want to get your callback called.

transitionend is not fired when initial state and final state are the same

A transition generally occurs when a style-change-event occurs. That is, when the style of an element (a property or more's value) changes, the transition is started. The W3C Specs (as expected) doesn't define when a style change event is triggered and leaves it to the implementation.

Below is the most that I could find in W3C Specs about this particular topic (2nd para below anchor):

When a style change event occurs, implementations must start transitions based on the computed values that changed in that event.

Actually the below seems to be even more conclusive definition of when a transition should start. This is found towards the end of the section pointed to by this anchor:

If all of the following are true:

  • the element does not have a running transition for the property,
  • the before-change style is different from and can be interpolated with the after-change style for that property,
  • the element does not have a completed transition for the property or the end value of the completed transition is different from the after-change style for the property,
  • there is a matching transition-property value, and
  • the combined duration is greater than 0s,

then implementations must remove the completed transition (if present) from the set of completed transitions and start a transition whose:

  • start time is the time of the style change event plus the matching transition delay,
  • end time is the start time plus the matching transition duration,
  • start value is the value of the transitioning property in the before-change style,
  • end value is the value of the transitioning property in the after-change style,
  • reversing-adjusted start value is the same as the start value, and
    reversing shortening factor is 1.

Now based on my understanding of how UAs work and how they would have been optimized, I do not see any reason for them to fire a transition start event when none of the properties set on the element is undergoing a change. It would be a overkill and extra load on the UA which could easily be avoided. When there is no transition start event itself, there is almost no way that a transition end event will be fired in such cases.

So, it looks like you'd most likely have to use some dummy property changes (or) use a timer whose value is equal to the transition-duration + transition-delay to mimic the transitionend.

event transitionend is calling a function twice in React?

There are few problems here

  1. You are adding an event listener inside an event handler.
    This will cause more and more event listeners to be added every time you click. To fix this, add it only once on mount using a useEffect:

    useEffect(() => { 
    divRef.current.addEventListener(
    "transitionend",
    settingHeightForTransition
    );
    }, []);
  2. The transition property itself it part of styles being applied. To fix this, always keep transition on the element using a class:

    <div
    className={"container " + (clicked ? "close" : "open")}
    style={{maxHeight: `${clicked? 0 : '200px'}`}}

    I recommend using classes for common styles. Also using something like StyledComponents will make it a lot easier to set computed styles.

Edit hungry-meitner-qxhtl



Related Topics



Leave a reply



Submit