web-dev-qa-db-fra.com

Événements de transition CSS3

Existe-t-il des événements déclenchés par un élément pour vérifier si une transition css3 a commencé ou se termine?

187

Brouillon des transitions CSS du W3C

L’achèvement d’une transition CSS génère un événement DOM correspondant. Un événement est déclenché pour chaque propriété soumise à une transition. Cela permet à un développeur de contenu d'effectuer des actions synchronisées avec l'achèvement d'une transition.


Webkit

Pour déterminer quand une transition est terminée, définissez une fonction d'écoute d'événements JavaScript pour l'événement DOM envoyé à la fin d'une transition. L'événement est une instance de WebKitTransitionEvent et son type est webkitTransitionEnd.

box.addEventListener( 'webkitTransitionEnd', 
    function( event ) { alert( "Finished transition!" ); }, false );

Mozilla

Un seul événement est déclenché à la fin des transitions. Dans Firefox, l'événement est transitionend, dans Opera, oTransitionEnd et dans WebKit, il s'agit de webkitTransitionEnd.

Opéra

Un type d'événement de transition est disponible. L'événement oTransitionEnd se produit à la fin de la transition.

Internet Explorer

L'événement transitionend se produit à la fin de la transition. Si la transition est supprimée avant la fin, l'événement ne sera pas déclenché.


Débordement de pile: comment normaliser les fonctions de transition CSS3 sur les navigateurs?

210
Davor Lucic

J'utilisais l'approche donnée par Pete, mais j'ai maintenant commencé à utiliser les éléments suivants

$(".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 ce qui suit 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 (  ._.)
  }


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

}(jQuery);

Notez qu'ils incluent également une fonction emulateTransitionEnd qui peut être nécessaire pour garantir qu'un rappel a toujours lieu.

  // 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
  }

Sachez que, parfois, cet événement ne se déclenche pas, généralement lorsque les propriétés ne changent pas ou qu’une peinture n’est pas déclenchée. Pour nous assurer de toujours recevoir un rappel, définissons un délai qui déclenchera l’événement manuellement.

http://blog.alexmaccaw.com/css-transitions

70
Tom

Tous les navigateurs modernes supporte maintenant l'événement sans préfixe:

element.addEventListener('transitionend', callback, false);

Fonctionne dans les dernières versions de Chrome, Firefox et Safari. Même IE10 +.

58
neave

Dans Opera 12, lorsque vous liez en utilisant le code JavaScript simple, 'oTransitionEnd' fonctionnera:

document.addEventListener("oTransitionEnd", function(){
    alert("Transition Ended");
});

cependant, si vous vous reliez via jQuery, vous devez utiliser 'otransitionend'

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

Si vous utilisez Modernizr ou bootstrap-transition.js, vous pouvez simplement faire un changement:

var transEndEventNames = {
    'WebkitTransition' : 'webkitTransitionEnd',
    'MozTransition'    : 'transitionend',
    'OTransition'      : 'oTransitionEnd otransitionend',
    'msTransition'     : 'MSTransitionEnd',
    'transition'       : 'transitionend'
},
transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];

Vous pouvez trouver quelques informations ici aussi http://www.ianlunn.co.uk/blog/articles/opera-12-otransitionend-bugs-and-workarounds/

16
Peter

Juste pour le plaisir, ne fais pas ça!

$.fn.transitiondone = function () {
  return this.each(function () {
    var $this = $(this);
    setTimeout(function () {
      $this.trigger('transitiondone');
    }, (parseFloat($this.css('transitionDelay')) + parseFloat($this.css('transitionDuration'))) * 1000);
  });
};


$('div').on('mousedown', function (e) {
  $(this).addClass('bounce').transitiondone();
});

$('div').on('transitiondone', function () {
  $(this).removeClass('bounce');
});
6
yckart

Si vous voulez simplement détecter une seule fin de transition, sans utiliser de framework JS, voici une petite fonction utilitaire pratique:

function once = function(object,event,callback){
    var handle={};

    var eventNames=event.split(" ");

    var cbWrapper=function(){
        eventNames.forEach(function(e){
            object.removeEventListener(e,cbWrapper, false );
        });
        callback.apply(this,arguments);
    };

    eventNames.forEach(function(e){
        object.addEventListener(e,cbWrapper,false);
    });

    handle.cancel=function(){
        eventNames.forEach(function(e){
            object.removeEventListener(e,cbWrapper, false );
        });
    };

    return handle;
};

Usage:

var handler = once(document.querySelector('#myElement'), 'transitionend', function(){
   //do something
});

alors si vous souhaitez annuler à un moment donné, vous pouvez toujours le faire avec

handler.cancel();

C'est bon pour d'autres utilisations d'événement aussi :)

3
OpherV