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
}
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
});
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);
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 ...
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');
});
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
plural: les gestionnaires sont renvoyés plusieurs fois, même si nous nous attendons à être renvoyés par un seul événement.
depth: les événements bouillonnent plus profondément dans l'arbre avant que notre gestionnaire ne les attrape.
Exemples:
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,
une touchend
peut être suivie par une mouseup
pour les mêmes raisons,
une animationstart
peut être suivie de nombreux autres événements similaires en fonction de la façon dont vous avez écrit le css,
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:
1er argument une référence de noeud,
2ème argument une chaîne représentant l'événement pour notre rappel et
3ème arg. notre rappel actuel.