¿Hay algún evento activado por un elemento para verificar si una transición css3 ha comenzado o finalizado?
¿Hay algún evento activado por un elemento para verificar si una transición css3 ha comenzado o finalizado?
Respuestas:
La finalización de una transición CSS genera un evento DOM correspondiente. Se dispara un evento por cada propiedad que sufre una transición. Esto permite a un desarrollador de contenido realizar acciones que se sincronizan con la finalización de una transición.
Para determinar cuándo se completa una transición, configure una función de escucha de eventos JavaScript para el evento DOM que se envía al final de una transición. El evento es una instancia de WebKitTransitionEvent, y su tipo es
webkitTransitionEnd
.
box.addEventListener( 'webkitTransitionEnd',
function( event ) { alert( "Finished transition!" ); }, false );
Hay un solo evento que se dispara cuando se completan las transiciones. En Firefox, el evento es
transitionend
, en OperaoTransitionEnd
, y en WebKitwebkitTransitionEnd
.
Hay un tipo de evento de transición disponible. El
oTransitionEnd
evento se produce al finalizar la transición.
El
transitionend
evento se produce al finalizar la transición. Si la transición se elimina antes de completarse, el evento no se activará.
Desbordamiento de pila: ¿Cómo normalizo las funciones de transición CSS3 en los navegadores?
Actualizar
Todos los navegadores modernos ahora admiten el evento no prefijado:
element.addEventListener('transitionend', callback, false);
https://caniuse.com/#feat=css-transitions
Estaba usando el enfoque dado por Pete, sin embargo, ahora he comenzado a usar lo siguiente
$(".myClass").one('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd',
function() {
//do something
});
Alternativamente, si usa bootstrap, simplemente puede hacer
$(".myClass").one($.support.transition.end,
function() {
//do something
});
Esto es porque incluyen lo siguiente en 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);
Tenga en cuenta que también incluyen una función emulateTransitionEnd que puede ser necesaria para garantizar que siempre se produzca una devolución de llamada.
// 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
}
Tenga en cuenta que a veces este evento no se dispara, generalmente en el caso en que las propiedades no cambian o no se activa una pintura. Para garantizar que siempre recibamos una devolución de llamada, establezcamos un tiempo de espera que active el evento manualmente.
Todos los navegadores modernos ahora admiten el evento no prefijado:
element.addEventListener('transitionend', callback, false);
Funciona en las últimas versiones de Chrome, Firefox y Safari. Incluso IE10 +.
En Opera 12 cuando se enlaza usando el JavaScript simple, 'oTransitionEnd' funcionará:
document.addEventListener("oTransitionEnd", function(){
alert("Transition Ended");
});
sin embargo, si vincula jQuery, debe usar 'otransitionend'
$(document).bind("otransitionend", function(){
alert("Transition Ended");
});
En caso de que esté utilizando Modernizr o bootstrap-transition.js, simplemente puede hacer un cambio:
var transEndEventNames = {
'WebkitTransition' : 'webkitTransitionEnd',
'MozTransition' : 'transitionend',
'OTransition' : 'oTransitionEnd otransitionend',
'msTransition' : 'MSTransitionEnd',
'transition' : 'transitionend'
},
transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];
Puede encontrar información aquí también http://www.ianlunn.co.uk/blog/articles/opera-12-otransitionend-bugs-and-workarounds/
¡Solo por diversión, no hagas esto!
$.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 simplemente desea detectar un solo final de transición, sin usar ningún marco JS, aquí hay una pequeña y conveniente función de utilidad:
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;
};
Uso:
var handler = once(document.querySelector('#myElement'), 'transitionend', function(){
//do something
});
entonces, si desea cancelar en algún momento, aún puede hacerlo con
handler.cancel();
También es bueno para otros usos de eventos :)