Обратный вызов при завершении перехода 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);
        });