Callback saat transisi CSS3 selesai


202

Saya ingin memudar elemen (transisi opacity ke 0) dan kemudian setelah selesai menghapus elemen dari DOM.

Di jQuery ini langsung karena Anda dapat menentukan "Hapus" yang akan terjadi setelah animasi selesai. Tetapi jika saya ingin menghidupkan menggunakan transisi CSS3 apakah ada untuk mengetahui kapan transisi / animasi telah selesai?



Jawaban:


334

Untuk transisi, Anda dapat menggunakan yang berikut untuk mendeteksi akhir transisi melalui jQuery:

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

Mozilla memiliki referensi yang sangat baik:

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions#Detecting_the_start_and_completion_of_a_transition

Untuk animasi sangat mirip:

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

Perhatikan bahwa Anda dapat meneruskan semua string acara yang diawali browser ke metode bind () secara bersamaan untuk mendukung acara yang dijalankan pada semua browser yang mendukungnya.

Memperbarui:

Per komentar yang ditinggalkan oleh Duck: Anda menggunakan .one()metode jQuery untuk memastikan pawang hanya menembak sekali. Sebagai contoh:

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

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

Pembaruan 2:

bind()Metode jQuery telah ditinggalkan, dan on()metode lebih disukai pada jQuery 1.7.bind()

Anda juga dapat menggunakan off()metode pada fungsi panggilan balik untuk memastikan itu akan diaktifkan hanya sekali. Berikut adalah contoh yang setara dengan menggunakan one()metode:

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

Referensi:


13
Perlu dicatat bahwa panggilan balik akan dipecat untuk setiap elemen anak yang transit juga. Ini sangat penting untuk diingat jika Anda bertanya-tanya mengapa panggilan balik Anda dipecat lebih dari yang Anda harapkan. Saya tidak mengetahui adanya solusi seperti sekarang.
Im

22
@Lev, Anda dapat dengan mudah mengurangi ini dengan membandingkan Target arus acara dengan targetnya. Jadi sesuatu seperti: function (event) {if (event.target === event.currentTarget) {/ * Do stuff * /}}
Jim Jeffers

5
Ya, saya menemukan itu tidak lama setelah saya menulis komentar. > _ <Terima kasih telah mempostingnya; Saya yakin itu akan membantu orang lain! :)
Im

9
Kami menggunakan .on()daripada .bind()untuk jQuery v1.7 + api.jquery.com/bind
olo

4
Semua browser modern sekarang mendukung acara yang tidak diperbaiki. caniuse.com/#feat=css-transitions Juga perhatikan bahwa jika Anda memiliki "transisiend webkitTransitionEnd" itu akan dipicu dua kali di Chrome.
Michael S.

17

Opsi lain adalah menggunakan Kerangka Transit jQuery untuk menangani transisi CSS3 Anda. Transisi / efek berfungsi dengan baik pada perangkat seluler dan Anda tidak perlu menambahkan satu baris transisi CSS3 yang berantakan di file CSS Anda untuk melakukan efek animasi.

Berikut adalah contoh yang akan mentransisikan opacity elemen ke 0 saat Anda mengkliknya dan akan dihapus setelah transisi selesai:

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

Demo JS Fiddle


Callback tidak berfungsi - mungkin karena perubahan api transit yang saya tidak tahu, tetapi contoh biola tidak berfungsi. Ini memicu metode sembunyikan sebelum animasi berjalan (dicoba dalam chrome)
Jonathan Liuti

@ JonathanLiuti diuji menggunakan FireFox 25, IE11, Chrome 31. Bekerja dengan baik.
ROFLwTIME

Ya @ROFLwTIME Anda benar sekali - sepertinya krom saya menjadi gila. Tes ulang biola hari ini setelah restart bersih dari chrome dan itu berfungsi seperti yang diharapkan. Salahku ! Maaf soal yang ini.
Jonathan Liuti

14

Ada animationendAcara yang bisa dilihat lihat dokumentasi di sini , juga untuk transitionanimasi css Anda bisa menggunakan transitionendacara tersebut

Tidak perlu perpustakaan tambahan ini semua bekerja dengan vanilla JS

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>


2
Ini adalah jawaban untuk tautan saja . Anda harus memperluas jawaban Anda untuk memasukkan sebanyak mungkin informasi di sini, dan menggunakan tautan hanya untuk referensi.
Selamat tinggal StackExchange

4
Memilih ini karena ini yang pertama yang tidak bergantung pada jQuery. Tidak masuk akal menebang seluruh pohon untuk cabang.
Aaron Mason

7

Bagi siapa saja yang mungkin berguna untuk hal ini, berikut ini adalah fungsi dependen jQuery yang saya berhasil dengan menerapkan animasi CSS melalui kelas CSS, kemudian mendapatkan panggilan balik dari setelah itu. Ini mungkin tidak berfungsi dengan baik karena saya menggunakannya di Aplikasi Backbone.js, tapi mungkin berguna.

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();
}

Saya menggunakannya agak seperti ini

cssAnimate.call($("#something"), "fadeIn", function() {
    console.log("Animation is complete");
    // Remove animation class name?
});

Ide asli dari http://mikefowler.me/2013/11/18/page-transitions-in-backbone/

Dan ini sepertinya berguna: http://api.jqueryui.com/addClass/


Memperbarui

Setelah berjuang dengan kode di atas dan opsi lain, saya akan menyarankan sangat berhati-hati dengan mendengarkan animasi CSS berakhir. Dengan berbagai animasi yang terjadi, ini bisa menjadi sangat cepat berantakan untuk mendengarkan acara. Saya akan sangat menyarankan perpustakaan animasi seperti GSAP untuk setiap animasi, bahkan yang kecil.


Terima kasih telah berbagi, saya telah menggunakannya dan diedit menambahkan e.stopImmediatePropagation(); self.trigger(this.whichAnimationEvent()); //for purge existing event callback.apply(self);
BomAle

5

Jawaban yang diterima saat ini diaktifkan dua kali untuk animasi di Chrome. Agaknya ini karena mengakui webkitAnimationEndserta animationEnd. Yang berikut ini pasti hanya akan menyala sekali:

/* 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);
        });

3
Saya akan menyarankan untuk memanggil fungsi whichAnimationEvent (), karena ini berkaitan dengan acara animasi.
Jakob Løkke Madsen
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.