javascript - Enabling vendor prefixes in CSS transitions make callback fires twice - Stack Overflow

I'm implementing an excellent solution (found here) to use a callback function a la jQuery when us

I'm implementing an excellent solution (found here) to use a callback function a la jQuery when using CSS transitions.

The problem is that if I use vendor prefixes, Chrome at least binds two events: one for webkitTransitionEnd and the second one for transitionend and, of course, fires the callback twice. Here's my piece of code:

jQuery("#main").one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(e) {
  console.log("POUM!");
});

Am I doing something wrong?

I'm implementing an excellent solution (found here) to use a callback function a la jQuery when using CSS transitions.

The problem is that if I use vendor prefixes, Chrome at least binds two events: one for webkitTransitionEnd and the second one for transitionend and, of course, fires the callback twice. Here's my piece of code:

jQuery("#main").one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(e) {
  console.log("POUM!");
});

Am I doing something wrong?

Share edited May 8, 2014 at 4:35 alex 491k204 gold badges889 silver badges991 bronze badges asked Aug 7, 2013 at 14:50 user900362user900362
Add a ment  | 

3 Answers 3

Reset to default 5

You're not doing anything wrong. Chrome just uses both the prefixed and un-prefixed versions.

There are a couple options:

  1. Using an outside variable.

    var fired = false;
    jQuery("#main").one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(e) {
        if ( ! fired ) {
            fired = true;
            console.log("POUM!");
        }
    });
    
  2. Using some kind of detection to get a single variable for transitionend (the below uses Modernizr, and is taken from their documentation):

    var transitionend = (function(transition) {
         var transEndEventNames = {
             'WebkitTransition' : 'webkitTransitionEnd',// Saf 6, Android Browser
             'MozTransition'    : 'transitionend',      // only for FF < 15
             'transition'       : 'transitionend'       // IE10, Opera, Chrome, FF 15+, Saf 7+
        };
    
        return transEndEventNames[transition];
    })(Modernizr.prefixed('transition'));
    
    // then
    jQuery("#main").one(transitionend, function(e) {
        console.log("POUM!");
    });
    

NOTE:

Safari 6 seems to trigger onload for anything that is set in the CSS. So, if you have (assuming all prefixes)

#main {
    width: 40px;
    height: 40px;
    transition: all 200ms;
}

Safari will trigger the transitionend with width and height on load. There are a couple ways to get around this:

  • Use more specific transition-property (but if you set that in the CSS, it will still trigger)
  • Do the following in javascript (it's not the prettiest thing, but it should take care of that edge case and it still works in Chrome) fiddle

    var transitionProperty = 'background-color',
        startColor = jQuery("#main").on(transitionend, function(e) {
            var el = $(this);
            if ( transitionProperty === e.originalEvent.propertyName && el.css(transitionProperty) !== startColor ) {
                console.log("POUM!");
                // This is to make it only happen once.
                $(this).off(transitionend);
            }
        }).css(transitionProperty);
    

I had the same problem, with Chrome firing twice, once for "transitionend" and again for "webkitTransitionEnd". With inspiration from remyabel's solution, I ended up with something fairly simple.

jQuery("#main").one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(e) {
$(this).off("webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd    transitionend");
  console.log("POUM!");
});

Not sure if this addresses your issues, but from this link: http://ianlunn.co.uk/articles/opera-12-otransitionend-bugs-and-workarounds/

It quote says:

Yup, six! In Opera 11, the transitionEnd event fired twice for every one transition ending. In Opera 12, a transitionEnd event will fire six times whether binding via JavaScript or jQuery.

This is for Opera, but I'm assuming that the same problem applies to you. It then goes to say that you can alleviate this problem by doing:

$(document).bind("otransitionend", function(){
    $(this).unbind("otransitionend");
    alert("Transition Ended");
});

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745049681a4608309.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信