Devolución de llamada cuando finaliza la transición de CSS3


Me gustaría desvanecer un elemento (haciendo la transición de su opacidad a 0) y luego, cuando termine, eliminar el elemento del DOM.

En jQuery esto es sencillo, ya que puede especificar que "Eliminar" suceda después de que se complete una animación. Pero si deseo animar usando transiciones CSS3, ¿hay alguna manera de saber cuándo se ha completado la transición/animación?

Author: C.J., 2012-02-13

4 answers

Para las transiciones puede usar lo siguiente para detectar el final de una transición a través de jQuery:

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

Mozilla tiene una excelente referencia:

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

Para las animaciones es muy similar:

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

Tenga en cuenta que puede pasar todas las cadenas de eventos prefijadas por el navegador al método bind() simultáneamente para admitir el evento se activa en todos los navegadores que lo soportan.

Actualización:

Por el comentario dejado por Duck: se utiliza el método .one() de jQuery para asegurarse de que el controlador solo se dispara una vez. Por ejemplo:

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

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

Actualizar 2:

El método

JQuery bind() ha sido obsoleto, y el método on() se prefiere a partir de jQuery 1.7. bind()

También puede usar el método off() en la función de devolución de llamada para asegurarse de que se disparará solo una vez. Aquí hay un ejemplo que es equivalente a usar el método one():

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

Referencias:

 317
Author: Jim Jeffers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-13 17:58:49

Otra opción sería utilizar el jQuery Transit Framework para manejar sus transiciones CSS3. Las transiciones / efectos funcionan bien en dispositivos móviles y no tiene que agregar una sola línea de transiciones CSS3 desordenadas en su archivo CSS para hacer los efectos de animación.

Aquí hay un ejemplo que hará la transición de la opacidad de un elemento a 0 cuando haga clic en él y se eliminará una vez que se complete la transición:

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

JS Fiddle Demo

 16
Author: ROFLwTIME,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-21 12:19:54

Para cualquiera que esto podría ser útil, aquí hay una función dependiente de jQuery con la que tuve éxito para aplicar una animación CSS a través de una clase CSS, y luego obtener una devolución de llamada de después. Puede que no funcione perfectamente desde que lo usé en una columna vertebral.aplicación js, pero tal vez útil.

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

Lo usé un poco como esto

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

Idea original de http://mikefowler.me/2013/11/18/page-transitions-in-backbone /

Y esto parece útil: http://api.jqueryui.com/addClass /


Actualización

Después de luchar con el código anterior y otras opciones, sugeriría ser muy cauteloso con cualquier escucha de los extremos de animación CSS. Con múltiples animaciones en marcha, esto puede complicarse muy rápido para escuchar eventos. Yo sugeriría fuertemente una biblioteca de animación como GSAP para cada animación, incluso las más pequeñas.

 8
Author: David Sinclair,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-27 23:17:00

La respuesta aceptada actualmente se dispara dos veces para animaciones en Chrome. Presumiblemente, esto es porque reconoce webkitAnimationEnd así como animationEnd. Lo siguiente definitivamente solo se dispara una vez:

/* 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);
        });
 4
Author: Chuck Le Butt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-13 16:38:19