Czy są jakieś zdarzenia uruchamiane przez element w celu sprawdzenia, czy przejście css3 rozpoczęło się lub zakończyło?
Czy są jakieś zdarzenia uruchamiane przez element w celu sprawdzenia, czy przejście css3 rozpoczęło się lub zakończyło?
Odpowiedzi:
Zakończenie przejścia CSS generuje odpowiednie zdarzenie DOM. Zdarzenie jest uruchamiane dla każdej właściwości, która podlega przejściu. Umożliwia to twórcy treści wykonywanie działań synchronizujących się z zakończeniem przejścia.
Aby ustalić, kiedy przejście zostanie zakończone, ustaw funkcję nasłuchiwania zdarzeń JavaScript dla zdarzenia DOM wysyłanego na końcu przejścia. Zdarzenie jest instancją WebKitTransitionEvent, a jego typem jest
webkitTransitionEnd
.
box.addEventListener( 'webkitTransitionEnd',
function( event ) { alert( "Finished transition!" ); }, false );
Istnieje jedno zdarzenie, które jest uruchamiane po zakończeniu przejścia. W Firefoksie zdarzenie jest
transitionend
w OperzeoTransitionEnd
, a w WebKit jestwebkitTransitionEnd
.
Dostępny jest jeden rodzaj zdarzenia przejścia.
oTransitionEnd
Zdarzenie na zakończeniu transformacji.
transitionend
Zdarzenie na zakończeniu transformacji. Jeśli przejście zostanie usunięte przed zakończeniem, zdarzenie nie zostanie uruchomione.
Przepełnienie stosu: jak normalizować funkcje przejścia CSS3 w różnych przeglądarkach?
Aktualizacja
Wszystkie współczesne przeglądarki obsługują teraz nieokreślone zdarzenie:
element.addEventListener('transitionend', callback, false);
https://caniuse.com/#feat=css-transitions
Korzystałem z podejścia podanego przez Pete'a, ale teraz zacząłem stosować następujące
$(".myClass").one('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd',
function() {
//do something
});
Alternatywnie, jeśli używasz bootstrap, możesz po prostu to zrobić
$(".myClass").one($.support.transition.end,
function() {
//do something
});
Jest tak, ponieważ zawierają one następujące pliki w pliku 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);
Należy pamiętać, że zawierają one także funkcję emulateTransitionEnd, która może być potrzebna do zapewnienia, że zawsze nastąpi wywołanie zwrotne.
// 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
}
Należy pamiętać, że czasami to zdarzenie nie jest uruchamiane, zwykle w przypadku, gdy właściwości się nie zmieniają lub farba nie jest wyzwalana. Aby mieć pewność, że zawsze otrzymamy oddzwonienie, ustawmy limit czasu, który wyzwoli zdarzenie ręcznie.
Wszystkie współczesne przeglądarki obsługują teraz nieokreślone zdarzenie:
element.addEventListener('transitionend', callback, false);
Działa w najnowszych wersjach Chrome, Firefox i Safari. Nawet IE10 +.
W Operze 12, gdy łączysz się za pomocą zwykłego JavaScript, „oTransitionEnd” będzie działać:
document.addEventListener("oTransitionEnd", function(){
alert("Transition Ended");
});
jednak jeśli łączysz się przez jQuery, musisz użyć „otransitionend”
$(document).bind("otransitionend", function(){
alert("Transition Ended");
});
Jeśli korzystasz z Modernizr lub bootstrap-przejście.js, możesz po prostu dokonać zmiany:
var transEndEventNames = {
'WebkitTransition' : 'webkitTransitionEnd',
'MozTransition' : 'transitionend',
'OTransition' : 'oTransitionEnd otransitionend',
'msTransition' : 'MSTransitionEnd',
'transition' : 'transitionend'
},
transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];
Można znaleźć tutaj również informacje http://www.ianlunn.co.uk/blog/articles/opera-12-otransitionend-bugs-and-workarounds/
Tylko dla zabawy, nie rób tego!
$.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');
});
Jeśli chcesz po prostu wykryć tylko jeden koniec przejścia, bez korzystania ze struktury JS, oto mała wygodna funkcja narzędziowa:
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;
};
Stosowanie:
var handler = once(document.querySelector('#myElement'), 'transitionend', function(){
//do something
});
to jeśli chcesz anulować w pewnym momencie, nadal możesz to zrobić
handler.cancel();
Jest również dobry do innych zastosowań związanych z wydarzeniami :)