web-dev-qa-db-fra.com

Rappel lorsque la transition CSS3 est terminée

Je voudrais faire disparaître un élément en fondu (en passant son opacité à 0) et ensuite, une fois terminé, supprimer l'élément du DOM.

Dans jQuery, cela est simple puisque vous pouvez spécifier le "Supprimer" après la fin d'une animation. Mais si je souhaite animer en utilisant des transitions CSS3, est-il possible de savoir quand la transition/animation est terminée?

196
C.J.

Pour les transitions, vous pouvez utiliser les éléments suivants pour détecter la fin d'une transition via jQuery:

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

Mozilla a une excellente référence:

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

Pour les animations, c'est très similaire:

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

Notez que vous pouvez transmettre simultanément toutes les chaînes d'événement préfixées du navigateur à la méthode bind () afin de prendre en charge le déclenchement des événements sur tous les navigateurs qui la prennent en charge.

Mise à jour:

Selon le commentaire laissé par Duck: vous utilisez la méthode .one() de jQuery pour vous assurer que le gestionnaire ne se déclenche qu'une seule fois. Par exemple:

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

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

Mise à jour 2:

la méthode jQuery bind() est obsolète et la méthode on() est préférée à partir de jQuery 1.7. bind()

Vous pouvez également utiliser la méthode off() sur la fonction de rappel pour vous assurer qu'elle ne sera déclenchée qu'une seule fois. Voici un exemple qui équivaut à utiliser la méthode one():

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

Références:

330
Jim Jeffers

Une autre option serait d’utiliser le jQuery Transit Framework pour gérer vos transitions CSS3. Les transitions/effets fonctionnent bien sur les appareils mobiles et vous n'avez pas à ajouter une seule ligne de transitions désordonnées CSS3 dans votre fichier CSS pour pouvoir effectuer les effets d'animation.

Voici un exemple qui fera passer l'opacité d'un élément à 0 lorsque vous cliquez dessus et sera supprimé une fois la transition terminée:

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

JS Fiddle Demo

17
ROFLwTIME

Voici une fonction dépendante de jQuery avec laquelle j’ai eu du succès: appliquer une animation CSS via une classe CSS, puis obtenir un rappel par la suite. Cela peut ne pas fonctionner parfaitement car je l'avais utilisé dans une application Backbone.js, mais peut-être utile.

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();
}

Je l'ai utilisé un peu comme ça

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

Idée originale de http://mikefowler.me/2013/11/18/page-transitions-in-backbone/

Et cela semble pratique: http://api.jqueryui.com/addClass/


Mettre à jour

Après avoir lutté avec le code ci-dessus et d'autres options, je vous conseillerais d'être très prudent lorsque vous écoutez une animation CSS. Avec plusieurs animations en cours, cela peut devenir très compliqué pour l'écoute de l'événement. Je suggérerais fortement une bibliothèque d'animation comme GSAP pour chaque animation, même la plus petite.

8
David Sinclair

Il y a un événement animationend qui peut être observé, voir la documentation ici , également pour les animations css transition, vous pouvez utiliser l'événement transitionend

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>
6
Yehuda Schwartz

La réponse acceptée est actuellement déclenchée deux fois pour les animations dans Chrome. C'est probablement parce qu'il reconnaît webkitAnimationEnd ainsi que animationEnd. Ce qui suit ne sera certainement déclenché qu'une fois:

/* 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);
        });
5
Chuck Le Butt