Y a-t-il des événements déclenchés par un élément pour vérifier si une transition css3 a commencé ou se termine?
Y a-t-il des événements déclenchés par un élément pour vérifier si une transition css3 a commencé ou se termine?
Réponses:
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é qui subit une transition. Cela permet à un développeur de contenu d'effectuer des actions qui se synchronisent avec l'achèvement d'une transition.
Pour déterminer quand une transition se termine, définissez une fonction d'écoute d'événement JavaScript pour l'événement DOM qui est 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 );
Un seul événement est déclenché lorsque les transitions sont terminées. Dans Firefox, l'événement est
transitionend
, dans OperaoTransitionEnd
, et dans WebKit il l'estwebkitTransitionEnd
.
Il existe un type d'événement de transition disponible. L'
oTransitionEnd
événement se produit à la fin de la transition.
L'
transitionend
événement se produit à la fin de la transition. Si la transition est supprimée avant la fin, l'événement ne se déclenchera pas.
Stack Overflow: Comment normaliser les fonctions de transition CSS3 dans les navigateurs?
Mettre à jour
Tous les navigateurs modernes prennent désormais en charge l'événement sans préfixe:
element.addEventListener('transitionend', callback, false);
https://caniuse.com/#feat=css-transitions
J'utilisais l'approche donnée par Pete, mais j'ai maintenant commencé à utiliser ce qui suit
$(".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 ( ._.)
}
$(function () {
$.support.transition = transitionEnd()
})
}(jQuery);
Notez qu'ils incluent également une fonction emulateTransitionEnd qui peut être nécessaire pour garantir qu'un rappel se produit toujours.
// 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 dans le cas où les propriétés ne changent pas ou une peinture n'est pas déclenchée. Pour nous assurer que nous recevons toujours un rappel, définissons un délai d'expiration qui déclenchera l'événement manuellement.
Tous les navigateurs modernes prennent désormais en charge 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 +.
Dans Opera 12, lorsque vous liez en utilisant le JavaScript brut, 'oTransitionEnd' fonctionnera:
document.addEventListener("oTransitionEnd", function(){
alert("Transition Ended");
});
cependant si vous liez 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 également trouver des informations ici http://www.ianlunn.co.uk/blog/articles/opera-12-otransitionend-bugs-and-workarounds/
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');
});
Si vous souhaitez 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
});
puis si vous souhaitez annuler à un moment donné, vous pouvez toujours le faire avec
handler.cancel();
C'est également bon pour d'autres usages événementiels :)