Ci sono eventi generati da un elemento per verificare se una transizione css3 è iniziata o terminata?
Ci sono eventi generati da un elemento per verificare se una transizione css3 è iniziata o terminata?
Risposte:
Il completamento di una transizione CSS genera un evento DOM corrispondente. Viene generato un evento per ogni proprietà che subisce una transizione. Ciò consente a uno sviluppatore di contenuti di eseguire azioni che si sincronizzano con il completamento di una transizione.
Per determinare quando una transizione viene completata, impostare una funzione di listener di eventi JavaScript per l'evento DOM che viene inviato al termine di una transizione. L'evento è un'istanza di WebKitTransitionEvent e il suo tipo è
webkitTransitionEnd
.
box.addEventListener( 'webkitTransitionEnd',
function( event ) { alert( "Finished transition!" ); }, false );
C'è un singolo evento che viene generato al completamento delle transizioni. In Firefox, l'evento è
transitionend
, in OperaoTransitionEnd
, e in WebKit lo èwebkitTransitionEnd
.
È disponibile un tipo di evento di transizione. L'
oTransitionEnd
evento si verifica al completamento della transizione.
L'
transitionend
evento si verifica al completamento della transizione. Se la transizione viene rimossa prima del completamento, l'evento non si attiverà.
Stack Overflow: come posso normalizzare le funzioni di transizione CSS3 tra i browser?
Aggiornare
Tutti i browser moderni ora supportano l'evento non risolto:
element.addEventListener('transitionend', callback, false);
https://caniuse.com/#feat=css-transitions
Stavo usando l'approccio dato da Pete, tuttavia ora ho iniziato a usare quanto segue
$(".myClass").one('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd',
function() {
//do something
});
In alternativa, se usi bootstrap, puoi semplicemente farlo
$(".myClass").one($.support.transition.end,
function() {
//do something
});
Questo perché includono quanto segue in 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);
Nota che includono anche una funzione emulateTransitionEnd che potrebbe essere necessaria per garantire che si verifichi sempre un callback.
// 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
}
Tieni presente che a volte questo evento non si attiva, di solito nel caso in cui le proprietà non cambiano o una vernice non viene attivata. Per essere sicuri di ricevere sempre una richiamata, impostiamo un timeout che attiverà manualmente l'evento.
Tutti i browser moderni ora supportano l'evento non risolto:
element.addEventListener('transitionend', callback, false);
Funziona con le ultime versioni di Chrome, Firefox e Safari. Anche IE10 +.
In Opera 12 quando esegui il bind utilizzando il semplice JavaScript, 'oTransitionEnd' funzionerà:
document.addEventListener("oTransitionEnd", function(){
alert("Transition Ended");
});
tuttavia se esegui il binding tramite jQuery, devi utilizzare "otransitionend"
$(document).bind("otransitionend", function(){
alert("Transition Ended");
});
Nel caso in cui tu stia usando Modernizr o bootstrap-transizione.js puoi semplicemente fare una modifica:
var transEndEventNames = {
'WebkitTransition' : 'webkitTransitionEnd',
'MozTransition' : 'transitionend',
'OTransition' : 'oTransitionEnd otransitionend',
'msTransition' : 'MSTransitionEnd',
'transition' : 'transitionend'
},
transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];
Puoi trovare alcune informazioni anche qui http://www.ianlunn.co.uk/blog/articles/opera-12-otransitionend-bugs-and-workarounds/
Solo per divertimento, non farlo!
$.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');
});
Se vuoi semplicemente rilevare solo una singola estremità di transizione, senza usare alcun framework JS ecco una piccola funzione di utilità:
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
});
quindi se desideri annullare a un certo punto puoi comunque farlo
handler.cancel();
È buono anche per altri utilizzi di eventi :)