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?
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.
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 );
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 dewebkitTransitionEnd
.
Un type d'événement de transition est disponible. L'événement
oTransitionEnd
se produit à la fin de la transition.
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?
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.
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 +.
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/
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 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 :)