简体   繁体   中英

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

In the example below I'm doing background-color transition using CSS and trying to handle transitionend event for both divs.

Unfortunately, transitionend is not fired for div2 as initial and final background colors are the same:

 var div1 = $('#div1'); var div2 = $('#div2'); $('#toggle').on('click', function() { div1.toggleClass('toggled'); div2.toggleClass('toggled'); }) div1.on('transitionend', function() { console.log('div1 transitionend') }) div2.on('transitionend', function() { console.log('div2 transitionend') })
 div { width: 100px; height: 100px; transition: background-color .5s; } #div1 { background-color: red; } #div2 { background-color: green; } .toggled { background-color: green !important; }
 <script src="https://code.jquery.com/jquery-3.1.0.js"></script> <div id="div1"></div> <div id="div2"></div> <button id="toggle">Toggle animation</button>

How can I achive handling transitionend even in cases 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 (2 nd 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 .

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