web-dev-qa-db-ja.com

CSS3移行が終了したときのコールバック

要素をフェードアウトし(不透明度を0に移行)、終了したらDOMから要素を削除します。

JQueryでは、アニメーションの完了後に「削除」を指定できるため、これは簡単です。しかし、CSS3トランジションを使用してアニメーション化する場合、トランジション/アニメーションがいつ完了したかを知る必要がありますか?

194
C.J.

遷移の場合、次を使用して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()メソッドに同時に渡して、それをサポートするすべてのブラウザで発生するイベントをサポートできることに注意してください。

更新:

Duckが残したコメントごとに、jQueryの.one()メソッドを使用して、ハンドラーが1回だけ起動するようにします。例えば:

$("#someSelector").one("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function(){ ... });

$("#someSelector").one("animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd", function(){ ... });

更新2:

jQueryのbind()メソッドは廃止され、jQuery 1.7の時点でon()メソッドが推奨されています。 bind()

また、コールバック関数でoff()メソッドを使用して、確実に1回だけ起動されるようにすることもできます。 one()メソッドを使用するのと同等の例を次に示します。

$("#someSelector")
.on("animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd",
 function(e){
    // do something here
    $(this).off(e);
 });

参照:

330
Jim Jeffers

別のオプションは、jQuery Transit Frameworkを使用してCSS3トランジションを処理することです。トランジション/エフェクトはモバイルデバイスで良好に機能し、アニメーションエフェクトを実行するためにCSSファイルに乱雑なCSS3トランジションを1行追加する必要はありません。

以下は、要素をクリックすると要素の不透明度が0に遷移し、遷移が完了すると削除される例です。

$("#element").click( function () {
    $('#element').transition({ opacity: 0 }, function () { $(this).remove(); });
});

JS Fiddle Demo

17
ROFLwTIME

これが便利な人のために、CSSクラスを介してCSSアニメーションを適用し、その後コールバックを取得することに成功したjQuery依存関数を以下に示します。 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 のようなアニメーションライブラリを、すべてのアニメーション(小さなものも含む)に強くお勧めします。

8
David Sinclair

現在、受け入れられた答えは、Chromeのアニメーションに対して2回発動します。これは、おそらくwebkitAnimationEndanimationEndを認識するためです。以下は間違いなく一度だけ起動します:

/* 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);
        });
4
Chuck Le Butt

観察できる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 id="myDIV" onclick="this.style.top = '55px';">Click me to start animation.</div>
3
Yehuda Schwartz