Обратный вызов при завершении перехода CSS3
Я хотел бы ослабить элемент (переместив его непрозрачность на 0), а затем, когда закончите, удалите элемент из DOM.
В jQuery это прямолинейно, так как вы можете указать, что "Удалить" произойдет после завершения анимации. Но если я хочу оживить с помощью переходов CSS3, все равно знать, когда завершился переход/анимация?
Ответы
Ответ 1
Для переходов вы можете использовать следующее, чтобы определить конец перехода через jQuery:
$("#someSelector").bind("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function(){ ... });
У Mozilla есть отличная ссылка:
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions#Detecting_the_start_and_completion_of_a_transition
Для анимации это очень похоже:
$("#someSelector").bind("animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd", function(){ ... });
Обратите внимание, что вы можете передавать все строки событий с префиксом браузера одновременно в метод bind(), чтобы поддерживать срабатывание события во всех браузерах, которые его поддерживают.
Обновление:
Согласно оставленному Даком комментарию: вы используете метод jQuery .one()
, чтобы обработчик срабатывал только один раз. Например:
$("#someSelector").one("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function(){ ... });
$("#someSelector").one("animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd", function(){ ... });
Обновление 2:
Метод jQuery bind()
устарел, а метод on()
предпочтителен с jQuery 1.7
. bind()
Вы также можете использовать метод off()
в функции обратного вызова, чтобы обеспечить его запуск только один раз. Вот пример, который эквивалентен использованию метода one()
:
$("#someSelector")
.on("animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd",
function(e){
// do something here
$(this).off(e);
});
Ссылки:
Ответ 2
Другим вариантом будет использование jQuery Transit Framework для обработки ваших переходов CSS3. Переходы/эффекты хорошо работают на мобильных устройствах, и вам не нужно добавлять одну строку беспорядочных переходов CSS3 в ваш CSS файл, чтобы сделать эффекты анимации.
Вот пример, который переместит непрозрачность элемента в 0, когда вы нажмете на него, и будет удален после завершения перехода:
$("#element").click( function () {
$('#element').transition({ opacity: 0 }, function () { $(this).remove(); });
});
JS Fiddle Demo
Ответ 3
Для тех, кому это может быть удобно, вот функция, зависящая от jQuery, с которой я успел применить анимацию CSS через класс CSS, а затем получить обратный вызов после этого. Он может работать не так, поскольку я использовал его в приложении Backbone.js, но, возможно, полезен.
var cssAnimate = function(cssClass, callback) {
var self = this;
// Checks if correct animation has ended
var setAnimationListener = function() {
self.one(
"webkitAnimationEnd oanimationend msAnimationEnd animationend",
function(e) {
if(
e.originalEvent.animationName == cssClass &&
e.target === e.currentTarget
) {
callback();
} else {
setAnimationListener();
}
}
);
}
self.addClass(cssClass);
setAnimationListener();
}
Я использовал это вроде как
cssAnimate.call($("#something"), "fadeIn", function() {
console.log("Animation is complete");
// Remove animation class name?
});
Оригинальная идея http://mikefowler.me/2013/11/18/page-transitions-in-backbone/
И это кажется удобным: http://api.jqueryui.com/addClass/
Обновление
После борьбы с указанным выше кодом и другими параметрами я предлагаю быть очень осторожным при любом прослушивании концов CSS-анимации. При многократной анимации это может стать очень беспорядочным для прослушивания событий. Я бы настоятельно рекомендовал анимационную библиотеку, например GSAP для каждой анимации, даже для маленьких.
Ответ 4
Событие animationend
можно наблюдать, см. документацию здесь,
также для анимации CSS transition
вы можете использовать событие transitionend
document.getElementById("myDIV").addEventListener("transitionend", myEndFunction);
function myEndFunction() {
this.innerHTML = "transition event ended";
}
#myDIV {transition: top 2s; position: relative; top: 0;}
div {background: #ede;cursor: pointer;padding: 20px;}
<div id="myDIV" onclick="this.style.top = '55px';">Click me to start animation.</div>
Ответ 5
Принятый ответ в настоящее время дважды запускается для анимации в Chrome. Предположительно, это потому, что он распознает webkitAnimationEnd
, а также animationEnd
. Следующие, безусловно, будут срабатывать только один раз:
/* From Modernizr */
function whichTransitionEvent(){
var el = document.createElement('fakeelement');
var transitions = {
'animation':'animationend',
'OAnimation':'oAnimationEnd',
'MSAnimation':'MSAnimationEnd',
'WebkitAnimation':'webkitAnimationEnd'
};
for(var t in transitions){
if( transitions.hasOwnProperty(t) && el.style[t] !== undefined ){
return transitions[t];
}
}
}
$("#elementToListenTo")
.on(whichTransitionEvent(),
function(e){
console.log('Transition complete! This is the callback!');
$(this).off(e);
});