web-dev-qa-db-fra.com

Comment utiliser transitionend dans jQuery?

Je dois détecter si une transition CSS est terminée avant de permettre à une fonction de se répéter, pour éviter de gâcher les marges. 

Alors, comment cam j'ai quelque chose comme

if (transitionend == true) {
  // do stuff
} else {
  // do nothing
}
32
JacobTheDev

Le code ci-dessous déclenchera l'événement transitionend pour le ou les éléments que vous avez dans la variable $ element. Il existe quatre noms d'événements différents, car ils couvrent toutes les incohérences entre les navigateurs. Remplacez le commentaire "// votre gestionnaire d'événements" par le code que vous souhaitez exécuter lorsque l'événement est déclenché.

$element.on('transitionend webkitTransitionEnd oTransitionEnd', function () {
    // your event handler
});
79
xram

Je pense que ce link pourrait vous être utile.

Un seul événement est déclenché à la fin des transitions. Dans Firefox, l'événement est transitionend, dans Opera, OTransitionEnd et dans WebKit c'est webkitTransitionEnd. 

el.addEventListener("transitionend", updateTransition, true);
6
Amin Eshaq

Utilisez jQuery data pour attacher des données avec état à l’élément. Utilisez une valeur booléenne pour "bloquer" les événements et inverser la variable booléenne une fois la transition terminée. Utilisez le code de xram pour connecter tous les événements de transition entre navigateurs simultanément.

Donc, pour votre exemple ...

  1. onclick set this.data ('transitioning', true)
  2. lorsque la transition se déclenche, définissez this.data ('transitioning', false)
  3. n'effectuez pas d'animation si this.data ('transitioning') == true. ceci est capturé et vérifié dans votre événement click.
2
Allison A

Vous pouvez créer une méthode qui gardera à l'esprit lorsque la fin de la transition a été appelée la dernière fois et ne déclenche donc le rappel qu'une seule fois.

function transitionEndsOnce($dom, callback) {
  var tick = Date.now();
  $dom.on('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd', function(e) {
    var diff = Date.now() - tick;
    tick = Date.now();
    if (diff > 20) { // this number can be changed, but normally all the event trigger are done in the same time
      return callback && callback(e);
    }
  });
}

puis utilisez-le simplement de cette façon

transitionEndsOnce($('...'), function(e){
  console.log('transition ends once');
});
1
Pouya

J'ai remarqué des questions similaires telles que "comment puis-je capturer des événements sensibles?" ou "événements de souris?" etc.

Ils sont tous similaires pour ces points de vue

  1. plural: les gestionnaires sont renvoyés plusieurs fois, même si nous nous attendons à être renvoyés par un seul événement.

  2. depth: les événements bouillonnent plus profondément dans l'arbre avant que notre gestionnaire ne les attrape. 

Exemples:

  1. une touchstart peut être suivie par une mousedown et vice versa dans un appareil doté à la fois d'une souris et d'un écran tactile,

  2. une touchend peut être suivie par une mouseup pour les mêmes raisons,

  3. une animationstart peut être suivie de nombreux autres événements similaires en fonction de la façon dont vous avez écrit le css,

  4. une animationend peut également être suivie de nombreux événements similaires pour les raisons susmentionnées.

Si nous devons renvoyer notre gestionnaire une fois par un ensemble d'événements similaires, c'est-à-dire d'événements produits par une seule action, comme une personne qui appuie sur qc. nous devons introduire un event lock et utiliser 2 gestionnaires l'un au début d'un événement et l'autre à la fin même si nous n'avons pas besoin ou ne voulons pas d'un gestionnaire de l'événement parallèle.

Le lock peut être une propriété du nœud parent higer dans l’arbre, comme vous l’avez deviné.

Pour le couple d'événement infâme: animationstart - animationend une telle fonction peut être:

var oneTransition = (function(){
   var $parent,
       type,
       callback,
       unlockCallback,
       newCallback,
       start = 'webkitTransitionStart otransitionstart oTransitionStart msTransitionStart transitionstart',
       end = 'webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend';

   unlockCallback = function(){
      $parent.data('oneTransitionLock', false);
   };

   newCallback = function(e){
      if($parent.data('oneTransitionLock'))
         return;
      else
         $parent.data('oneTransitionLock', true);

      callback(e);
   };

   return function(){
      var args = Array.prototype.slice.call(arguments, 0);

      $parent = $(args[0]);     // 1st arg
      type = args[1];           // 2nd arg
      callback = args[2];       // 3rd arg

      if((args.length < 3) || ((type != 'start') && (type != 'end')) || (typeof(callback) != 'function'))
         return;

      $parent.off(start).off(end);
      if(type == 'start'){
         $parent.data('oneTransitionLock', false);
         $parent.on(start, newCallback);
         $parent.on(end, unlockCallback);
      }else if(type == 'end'){
         $parent.on(start, unlockCallback);
         $parent.on(end, newCallback);
      }
   }
})();

et vous pouvez l'appeler comme:

oneTransition(node, 'start' or 'end', funcion(){...});

La partie intéressante est qu’elle peut être exécutée au début ou à la fin de l’animation:

  1. 1er argument une référence de noeud,

  2. 2ème argument une chaîne représentant l'événement pour notre rappel et

  3. 3ème arg. notre rappel actuel.

jsFiddle

0
centurian