Rappel sur la transition CSS

Réponses:

82

Je sais que Safari implémente un rappel webkitTransitionEnd que vous pouvez attacher directement à l'élément avec la transition.

Leur exemple (reformaté en plusieurs lignes):

box.addEventListener( 
     'webkitTransitionEnd', 
     function( event ) { 
         alert( "Finished transition!" ); 
     }, false );
Doug Neiner
la source
y a-t-il la même chose pour un autre navigateur que le webkit?
meo le
6
oui, 'transitionend' pour Mozilla et 'oTransitionEnd' dans Opera.
qqryq
2
que fait le faux à la fin?
meo
@meo Cela a quelque chose à voir avec l' thisélément à l'intérieur du rappel. Mais c'est un paramètre obligatoire, donc dans ce cas, il remplit simplement l'exigence.
Doug Neiner
8
@DougNeiner Le faux à la fin est pour useCaptureMode. Lorsqu'un événement se produit, il y a deux phases - la première phase est le mode capture, la seconde est le mode bulle. En mode capture, l'événement descend de l'élément body vers l'élément spécifié. Il entre alors en mode bulle, où il fait l'inverse. Ce dernier paramètre faux spécifie que vous souhaitez que l'écouteur d'événements se produise en mode bulle. Une utilisation de ceci est d'attacher des gestionnaires d'événements juste avant qu'ils ne soient nécessaires en mode bulle. =) 37signals.com/svn/posts/…
rybosome
103

Oui, si de telles choses sont prises en charge par le navigateur, un événement est déclenché une fois la transition terminée. L'événement réel diffère cependant d'un navigateur à l'autre:

  • Utilisation des navigateurs Webkit (Chrome, Safari) webkitTransitionEnd
  • Firefox utilise transitionend
  • IE9 + utilise msTransitionEnd
  • Opera utilise oTransitionEnd

Cependant, vous devez être conscient que webkitTransitionEndcela ne se déclenche pas toujours! Cela m'a surpris à plusieurs reprises et semble se produire si l'animation n'avait aucun effet sur l'élément. Pour contourner ce problème, il est logique d'utiliser un délai d'expiration pour déclencher le gestionnaire d'événements dans le cas où il n'a pas été déclenché comme prévu. Un article de blog sur ce problème est disponible ici: http://www.cuppadev.co.uk/the-trouble-with-css-transitions/ <- 500 Internal Server Error

Dans cet esprit, j'ai tendance à utiliser cet événement dans un morceau de code qui ressemble un peu à ceci:

var transitionEndEventName = "XXX"; //figure out, e.g. "webkitTransitionEnd".. 
var elemToAnimate = ... //the thing you want to animate..
var done = false;
var transitionEnded = function(){
     done = true;
     //do your transition finished stuff..
     elemToAnimate.removeEventListener(transitionEndEventName,
                                        transitionEnded, false);
};
elemToAnimate.addEventListener(transitionEndEventName,
                                transitionEnded, false);

//animation triggering code here..

//ensure tidy up if event doesn't fire..
setTimeout(function(){
    if(!done){
        console.log("timeout needed to call transition ended..");
        transitionEnded();
    }
}, XXX); //note: XXX should be the time required for the
        //animation to complete plus a grace period (e.g. 10ms) 

Remarque: pour obtenir le nom de fin de l'événement de transition, vous pouvez utiliser la méthode publiée comme réponse dans: Comment normaliser les fonctions de transition CSS3 dans les navigateurs? .

Remarque: cette question est également liée: - aux événements de transition CSS3

Mark Rhodes
la source
2
C'est une réponse beaucoup plus complète que celle acceptée. Pourquoi n'est-ce pas plus voté.
Wes
Rappelez - vous d'appeler transitionEndedHandlerà transitionEnded(ou changement transitionEndedpar transitionEndedHandlerdans addEventListeneret removeEventListeneret appel transitionEndeden transitionEndedHandler)
Miquel
Merci @Miquel; Je pense que je viens de l'utiliser transitionEndedquand je voulais dire transitionEndedHandler.
Mark Rhodes
Je crois que le problème de Chromium pour cela peut être trouvé ici: code.google.com/p/chromium/issues/detail?id=388082 Bien que, le dernier commentaire semble (à tort à mon avis) le réduire en tant que bogue et donc est actuellement marqué comme "ne résoudra pas".
Willster
Pas besoin de noms différents de nos jours caniuse.com/#feat=css-transitions
Juan Mendes
43

J'utilise le code suivant, c'est beaucoup plus simple que d'essayer de détecter l'événement final spécifique utilisé par un navigateur.

$(".myClass").one('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd', 
function() {
 //do something
});

Alternativement, si vous utilisez bootstrap, vous pouvez simplement faire

$(".myClass").one($.support.transition.end,
function() {
 //do something
});

C'est parce qu'ils incluent les éléments suivants dans bootstrap.js

+function ($) {
  'use strict';

  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
  // ============================================================

  function transitionEnd() {
    var el = document.createElement('bootstrap')

    var transEndEventNames = {
      'WebkitTransition' : 'webkitTransitionEnd',
      'MozTransition'    : 'transitionend',
      'OTransition'      : 'oTransitionEnd otransitionend',
      'transition'       : 'transitionend'
    }

    for (var name in transEndEventNames) {
      if (el.style[name] !== undefined) {
        return { end: transEndEventNames[name] }
      }
    }

    return false // explicit for ie8 (  ._.)
  }

  // http://blog.alexmaccaw.com/css-transitions
  $.fn.emulateTransitionEnd = function (duration) {
    var called = false, $el = this
    $(this).one($.support.transition.end, function () { called = true })
    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
    setTimeout(callback, duration)
    return this
  }

  $(function () {
    $.support.transition = transitionEnd()
  })

}(jQuery);
À M
la source
2
Ceci est plus lent car il doit rechercher dans toute cette liste à chaque fois que l'événement se produit pour voir s'il est le bon.
phreakhead
3
@phreakhead Les performances de l'une de ces approches seront très similaires
Tom
6

Le plugin jQuery.transit , un plugin pour les transformations et transitions CSS3, peut appeler vos animations CSS à partir d'un script et vous donner un rappel.

Brian
la source
5

Ceci peut facilement être réalisé avec l' transitionendévénement voir la documentation ici Un exemple simple:

document.getElementById("button").addEventListener("transitionend", myEndFunction);

function myEndFunction() {
	this.innerHTML = "Transition event ended";
}
#button {transition: top 2s; position: relative; top: 0;}
<button id="button" onclick="this.style.top = '55px';">Click me to start animation</button>

Yehuda Schwartz
la source
1
C'est la bonne réponse de nos jours, il n'est plus nécessaire d'avoir des préfixes. caniuse.com/#feat=css-transitions
Juan Mendes