backbone.viewkit icon indicating copy to clipboard operation
backbone.viewkit copied to clipboard

Transition end event doesn't always fire

Open scttnlsn opened this issue 12 years ago • 8 comments

If the value of the transition property does not change the transition end event does not fire. Use a setTimeout to ensure that an end event is always triggered.

scttnlsn avatar Jan 31 '13 18:01 scttnlsn

I also noticed that transitionEnd and transforms are only implemented for webkit (which makes sense considering this is aimed at mobile apps). Completely up to your discretion, but this is how I (very hastily) patched this to support latest IE and Firefox (inserted at L216 before assigning var Config = ViewKit.Transition.Config):

    var browser = $.browser;
    var prefix;
    prefix = browser.mozilla === true ? (Math.floor(browser.version) === 11 ? '' : '-moz-') : (browser.msie === true ? '' : '-webkit-');

    function whichTransitionEvent(){
        var t;
        var el = document.createElement('fakeelement');
        var transitions = {
          'transition':'transitionend',
          'OTransition':'oTransitionEnd',
          'MozTransition':'transitionend',
          'WebkitTransition':'webkitTransitionEnd'
        }

        for(t in transitions){
            if( el.style[t] !== undefined ){
                return transitions[t];
            }
        }
    }

    transitionEnd = whichTransitionEvent();

    var Config = ViewKit.Transition.Config = {
        transform: prefix + 'transform',
        transition: prefix + 'transition',
        transitionEnd: transitionEnd
    };

edit: some issues with IE11 reporting as "Mozilla" in $.browser (wtf right?). This now works for Chrome, Chrome Canary, IE10 + IE11 and Firefox.

StevenLangbroek avatar May 27 '14 13:05 StevenLangbroek

Nice! Could the prefix be set when checking for the existence of the various transition names?

scttnlsn avatar May 29 '14 18:05 scttnlsn

Not sure what you mean?

StevenLangbroek avatar Jun 01 '14 11:06 StevenLangbroek

When you're setting the prefix you check the browser object (i.e. $.browser.msie, $.browser.mozilla) but when determining the transitionEnd event you loop through a bunch of possible names. I'm just curious why you needed to use those two different techniques since I'm not very familiar with the nuances of all these names.

For example, instead of checking $.browser don't we know that if the transitionEnd event is 'webkitTransitionEnd' then the prefix is '-webkit'? Or are there edge cases where that is not true?

scttnlsn avatar Jun 01 '14 13:06 scttnlsn

Yeah I guess you could. Didn't find a specific function for it in either Modernizr (Modernizr.prefixed returns a prefixed js-version of css properties, not just the prefix), and wanted some control over it, but I guess this should be fairly easy to write.

StevenLangbroek avatar Jun 03 '14 07:06 StevenLangbroek

Check out how leaflet does it:

https://github.com/Leaflet/Leaflet/blob/master/src/dom/DomUtil.js#L172 and https://github.com/Leaflet/Leaflet/blob/master/src/dom/DomUtil.js#L139

I wrestled with transitionEnd not firing the whole last week. I worked around it by adding a small random number (Math.random() / 10000) to one of the parameters. Depends on the parameters of course, but it might make the code simpler than using setTimeout.

fab1an avatar Jun 13 '14 20:06 fab1an

Thanks @fab1an, adding 0.0001 to scale() transform parameter transitionend event is always fired. Not elegant but functional! ;-)

physiocoder avatar Jun 21 '14 23:06 physiocoder

Here's a solution that I used: because modern browser support multiple background images, you can randomly position a single pixel base64 encoded transparent gif. Every update of the Elements.style repositions this transparent gif. Helpful if you want to always trigger transition without visible change to the element.

background-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7); background-position: 79px 237px;

gwiant avatar Nov 22 '16 04:11 gwiant