Callback when CSS3 transition finishes

后端 未结 5 1844
野的像风
野的像风 2020-11-22 09:30

I\'d like to fade out an element (transitioning its opacity to 0) and then when finished remove the element from the DOM.

In jQuery this is straight forward since yo

相关标签:
5条回答
  • 2020-11-22 10:10

    For anyone that this might be handy for, here is a jQuery dependent function I had success with for applying a CSS animation via a CSS class, then getting a callback from afterwards. It may not work perfectly since I had it being used in a Backbone.js App, but maybe useful.

    var cssAnimate = function(cssClass, callback) {
        var self = this;
    
        // Checks if correct animation has ended
        var setAnimationListener = function() {
            self.one(
                "webkitAnimationEnd oanimationend msAnimationEnd animationend",
                function(e) {
                    if(
                        e.originalEvent.animationName == cssClass &&
                        e.target === e.currentTarget
                    ) {
                        callback();
                    } else {
                        setAnimationListener();
                    }
                }
            );
        }
    
        self.addClass(cssClass);
        setAnimationListener();
    }
    

    I used it kinda like this

    cssAnimate.call($("#something"), "fadeIn", function() {
        console.log("Animation is complete");
        // Remove animation class name?
    });
    

    Original idea from http://mikefowler.me/2013/11/18/page-transitions-in-backbone/

    And this seems handy: http://api.jqueryui.com/addClass/


    Update

    After struggling with the above code and other options, I would suggest being very cautious with any listening for CSS animation ends. With multiple animations going on, this can get messy very fast for event listening. I would strongly suggest an animation library like GSAP for every animation, even the small ones.

    0 讨论(0)
  • 2020-11-22 10:15

    The accepted answer currently fires twice for animations in Chrome. Presumably this is because it recognizes webkitAnimationEnd as well as animationEnd. The following will definitely only fires once:

    /* From Modernizr */
    function whichTransitionEvent(){
    
        var el = document.createElement('fakeelement');
        var transitions = {
            'animation':'animationend',
            'OAnimation':'oAnimationEnd',
            'MSAnimation':'MSAnimationEnd',
            'WebkitAnimation':'webkitAnimationEnd'
        };
    
        for(var t in transitions){
            if( transitions.hasOwnProperty(t) && el.style[t] !== undefined ){
                return transitions[t];
            }
        }
    }
    
    $("#elementToListenTo")
        .on(whichTransitionEvent(),
            function(e){
                console.log('Transition complete!  This is the callback!');
                $(this).off(e);
            });
    
    0 讨论(0)
  • 2020-11-22 10:16

    There is an animationend Event that can be observed see documentation here, also for css transition animations you could use the transitionend event

    There is no need for additional libraries these all work with vanilla JS

    document.getElementById("myDIV").addEventListener("transitionend", myEndFunction);
    function myEndFunction() {
    	this.innerHTML = "transition event ended";
    }
    #myDIV {transition: top 2s; position: relative; top: 0;}
    div {background: #ede;cursor: pointer;padding: 20px;}
    <div id="myDIV" onclick="this.style.top = '55px';">Click me to start animation.</div>

    0 讨论(0)
  • 2020-11-22 10:23

    Another option would be to use the jQuery Transit Framework to handle your CSS3 transitions. The transitions/effects perform well on mobile devices and you don't have to add a single line of messy CSS3 transitions in your CSS file in order to do the animation effects.

    Here is an example that will transition an element's opacity to 0 when you click on it and will be removed once the transition is complete:

    $("#element").click( function () {
        $('#element').transition({ opacity: 0 }, function () { $(this).remove(); });
    });
    

    JS Fiddle Demo

    0 讨论(0)
  • 2020-11-22 10:27

    For transitions you can use the following to detect the end of a transition via jQuery:

    $("#someSelector").bind("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function(){ ... });
    

    Mozilla has an excellent reference:

    https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions#Detecting_the_start_and_completion_of_a_transition

    For animations it's very similar:

    $("#someSelector").bind("animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd", function(){ ... });
    

    Note that you can pass all of the browser prefixed event strings into the bind() method simultaneously to support the event firing on all browsers that support it.

    Update:

    Per the comment left by Duck: you use jQuery's .one() method to ensure the handler only fires once. For example:

    $("#someSelector").one("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function(){ ... });
    
    $("#someSelector").one("animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd", function(){ ... });
    

    Update 2:

    jQuery bind() method has been deprecated, and on() method is preferred as of jQuery 1.7. bind()

    You can also use off() method on the callback function to ensure it will be fired only once. Here is an example which is equivalent to using one() method:

    $("#someSelector")
    .on("animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd",
     function(e){
        // do something here
        $(this).off(e);
     });
    

    References:

    • .off()

    • .one()

    0 讨论(0)
提交回复
热议问题