Callback pada transisi CSS

Jawaban:

82

Saya tahu bahwa Safari mengimplementasikan callback webkitTransitionEnd yang dapat Anda lampirkan langsung ke elemen dengan transisi.

Contoh mereka (diformat ulang menjadi beberapa baris):

box.addEventListener( 
     'webkitTransitionEnd', 
     function( event ) { 
         alert( "Finished transition!" ); 
     }, false );
Doug Neiner
sumber
apakah ada hal yang sama untuk browser lain selain webkit?
meo
6
ya, 'transisiend' untuk Mozilla & 'oTransitionEnd' di Opera.
qqryq
2
apa yang dilakukan oleh yang salah pada akhirnya?
meo
@meo Ini ada hubungannya dengan thiselemen di dalam callback. Tetapi itu adalah parameter yang dibutuhkan, jadi dalam hal ini hanya memenuhi persyaratan.
Doug Neiner
8
@DougNeiner Salah di akhir adalah untuk useCaptureMode. Ketika suatu peristiwa terjadi, ada dua fase - fase pertama adalah mode pengambilan, yang kedua adalah mode gelembung. Dalam mode pengambilan, peristiwa turun dari elemen tubuh ke elemen yang ditentukan. Kemudian memasuki mode gelembung, di mana ia melakukan kebalikannya. Parameter palsu terakhir itu menentukan bahwa Anda ingin event listener terjadi dalam mode gelembung. Salah satu kegunaannya adalah untuk memasang penangan kejadian tepat sebelum mereka dibutuhkan dalam mode gelembung. =) 37signals.com/svn/posts/…
rybosome
103

Ya, jika hal-hal seperti itu didukung oleh browser, maka sebuah peristiwa akan dipicu saat transisi selesai. Namun, acara sebenarnya berbeda di antara browser:

  • Penggunaan browser Webkit (Chrome, Safari) webkitTransitionEnd
  • Firefox menggunakan transitionend
  • IE9 + menggunakan msTransitionEnd
  • Opera menggunakan oTransitionEnd

Bagaimanapun Anda harus sadar bahwa webkitTransitionEndtidak selalu menembak! Hal ini telah membuat saya bingung beberapa kali, dan tampaknya terjadi jika animasi tidak berpengaruh pada elemen. Untuk menyiasatinya, masuk akal untuk menggunakan waktu tunggu untuk mengaktifkan penangan peristiwa jika tidak dipicu seperti yang diharapkan. Entri blog tentang masalah ini tersedia di sini: http://www.cuppadev.co.uk/the-trouble-with-css-transitions/ <- 500 Internal Server Error

Dengan pemikiran ini, saya cenderung menggunakan acara ini dalam potongan kode yang terlihat seperti ini:

var transitionEndEventName = "XXX"; //figure out, e.g. "webkitTransitionEnd".. 
var elemToAnimate = ... //the thing you want to animate..
var done = false;
var transitionEnded = function(){
     done = true;
     //do your transition finished stuff..
     elemToAnimate.removeEventListener(transitionEndEventName,
                                        transitionEnded, false);
};
elemToAnimate.addEventListener(transitionEndEventName,
                                transitionEnded, false);

//animation triggering code here..

//ensure tidy up if event doesn't fire..
setTimeout(function(){
    if(!done){
        console.log("timeout needed to call transition ended..");
        transitionEnded();
    }
}, XXX); //note: XXX should be the time required for the
        //animation to complete plus a grace period (e.g. 10ms) 

Catatan: untuk mendapatkan nama akhir peristiwa transisi, Anda dapat menggunakan metode yang diposting sebagai jawaban di: Bagaimana cara menormalkan fungsi Transisi CSS3 di seluruh browser? .

Catatan: pertanyaan ini juga terkait dengan: - Peristiwa transisi CSS3

Mark Rhodes
sumber
2
Ini adalah jawaban yang jauh lebih lengkap daripada jawaban yang diterima. Mengapa ini tidak lebih disukai.
Wes
Ingatlah untuk memanggil transitionEndedHandlerdi transitionEnded(atau perubahan transitionEndedoleh transitionEndedHandlerdi addEventListenerdan removeEventListenerdan panggilan transitionEndeddi transitionEndedHandler)
Miquel
Terima kasih @Miquel; pikir saya baru saja digunakan transitionEndedketika saya maksud transitionEndedHandler.
Mark Rhodes
Saya yakin masalah Chromium untuk ini dapat ditemukan di sini: code.google.com/p/chromium/issues/detail?id=388082 Meskipun, komentar terakhir tampaknya (menurut saya salah) menganggapnya sebagai bug dan oleh karena itu saat ini ditandai sebagai "tidak akan diperbaiki".
Willster
Tidak perlu nama yang berbeda saat ini caniuse.com/#feat=css-transitions
Juan Mendes
43

Saya menggunakan kode berikut, jauh lebih sederhana daripada mencoba mendeteksi peristiwa akhir tertentu yang digunakan browser.

$(".myClass").one('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd', 
function() {
 //do something
});

Atau jika Anda menggunakan bootstrap maka Anda dapat melakukannya

$(".myClass").one($.support.transition.end,
function() {
 //do something
});

Ini karena mereka menyertakan yang berikut ini di 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 (  ._.)
  }

  // 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
  }

  $(function () {
    $.support.transition = transitionEnd()
  })

}(jQuery);
Tom
sumber
2
Ini lebih lambat karena harus mencari melalui seluruh daftar itu setiap kali peristiwa terjadi untuk melihat apakah itu benar.
phreakhead
3
@phreakhead Penampilan salah satu pendekatan ini akan sangat mirip
Tom
6

The jQuery.transit Plugin , plugin untuk transformasi CSS3 dan transisi, dapat menghubungi animasi CSS Anda dari script dan memberikan panggilan balik.

Brian
sumber
5

Ini dapat dengan mudah dicapai dengan transitionendAcara, lihat dokumentasi di sini . Contoh sederhana:

document.getElementById("button").addEventListener("transitionend", myEndFunction);

function myEndFunction() {
	this.innerHTML = "Transition event ended";
}
#button {transition: top 2s; position: relative; top: 0;}
<button id="button" onclick="this.style.top = '55px';">Click me to start animation</button>

Yehuda Schwartz
sumber
1
Ini adalah jawaban yang benar saat ini, tidak perlu ada prefiks lagi. caniuse.com/#feat=css-transitions
Juan Mendes