Peristiwa transisi CSS3

Jawaban:

210

W3C CSS Transitions Draft

Penyelesaian CSS Transition menghasilkan Acara DOM yang sesuai. Suatu peristiwa dipecat untuk setiap properti yang mengalami transisi. Ini memungkinkan pengembang konten untuk melakukan tindakan yang disinkronkan dengan penyelesaian transisi.


Webkit

Untuk menentukan kapan transisi selesai, tetapkan fungsi pendengar acara JavaScript untuk acara DOM yang dikirim pada akhir transisi. Acara ini adalah turunan dari WebKitTransitionEvent, dan tipenya adalah webkitTransitionEnd.

box.addEventListener( 'webkitTransitionEnd', 
    function( event ) { alert( "Finished transition!" ); }, false );

Mozilla

Ada satu peristiwa yang dipecat ketika transisi selesai. Di Firefox, acara tersebut adalah transitionend, di Opera oTransitionEnd,, dan di WebKit webkitTransitionEnd.

Opera

Ada satu jenis acara transisi yang tersedia. The oTransitionEndperistiwa terjadi pada penyelesaian transisi.

Internet Explorer

The transitionendperistiwa terjadi pada penyelesaian transisi. Jika transisi dihapus sebelum selesai, acara tidak akan menyala.


Stack Overflow: Bagaimana cara menormalkan fungsi Transisi CSS3 di seluruh browser?

Davor Lucic
sumber
3
Perhatikan bahwa acara ini disebut "transisi" di firefox dan "oTransitionEnd" di Opera
Andreas Köberle
8
Belum ada yang menyebutkan apa pun tentang transisi-mulai bagian dari pertanyaan. Apakah tidak ada cara untuk mendaftarkan pengendali acara untuk dipecat sebelum transisi dimulai?
tyler
Apakah sekarang ada cara standar untuk mencapai ini? Sepertinya 2 tahun adalah waktu yang lama! Banyak hal telah berubah.
Mild Fuzz
@tyler saya tidak tahu bagaimana mengatasi kekurangan transisi-mulai.
Davor Lucic
@Mild Fuzz, pertanyaan terkait stackoverflow memiliki solusi menarik.
Davor Lucic
73

Memperbarui

Semua browser modern sekarang mendukung acara yang tidak diperbaiki:

element.addEventListener('transitionend', callback, false);

https://caniuse.com/#feat=css-transitions


Saya menggunakan pendekatan yang diberikan oleh Pete, namun saya sekarang mulai menggunakan yang berikut

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

Atau jika Anda menggunakan bootstrap maka Anda cukup melakukannya

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

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


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

}(jQuery);

Catatan mereka juga menyertakan fungsi emulateTransitionEnd yang mungkin diperlukan untuk memastikan panggilan balik selalu terjadi.

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

Ketahuilah bahwa terkadang acara ini tidak menyala, biasanya dalam kasus ketika properti tidak berubah atau cat tidak terpicu. Untuk memastikan kami selalu mendapat panggilan balik, mari tetapkan batas waktu yang akan memicu acara secara manual.

http://blog.alexmaccaw.com/css-transitions

Tom
sumber
3
Anda tidak dapat melakukan hal seperti itu. Dalam beberapa kasus, callbaack akan dipecat lebih dari sekali.
sebastian
11
Di browser yang menjaga awalan dan nama acara reguler tetap ada. Anda dapat mengatasinya dengan menggunakan .one bukannya .on
AlexG
61

Semua browser modern sekarang mendukung acara yang tidak diperbaiki:

element.addEventListener('transitionend', callback, false);

Bekerja di versi terbaru Chrome, Firefox dan Safari. Bahkan IE10 +.

neave
sumber
16

Di Opera 12 saat Anda mengikat menggunakan JavaScript biasa, 'oTransitionEnd' akan berfungsi:

document.addEventListener("oTransitionEnd", function(){
    alert("Transition Ended");
});

namun jika Anda mengikat melalui jQuery, Anda perlu menggunakan 'otransitionend'

$(document).bind("otransitionend", function(){
    alert("Transition Ended");
});

Jika Anda menggunakan Modernizr atau bootstrap-transition.js Anda cukup melakukan perubahan:

var transEndEventNames = {
    'WebkitTransition' : 'webkitTransitionEnd',
    'MozTransition'    : 'transitionend',
    'OTransition'      : 'oTransitionEnd otransitionend',
    'msTransition'     : 'MSTransitionEnd',
    'transition'       : 'transitionend'
},
transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];

Anda dapat menemukan beberapa info di sini juga http://www.ianlunn.co.uk/blog/articles/opera-12-otransitionend-bugs-and-workarounds/

Peter
sumber
6

Hanya untuk bersenang-senang, jangan lakukan ini!

$.fn.transitiondone = function () {
  return this.each(function () {
    var $this = $(this);
    setTimeout(function () {
      $this.trigger('transitiondone');
    }, (parseFloat($this.css('transitionDelay')) + parseFloat($this.css('transitionDuration'))) * 1000);
  });
};


$('div').on('mousedown', function (e) {
  $(this).addClass('bounce').transitiondone();
});

$('div').on('transitiondone', function () {
  $(this).removeClass('bounce');
});
yaart
sumber
3

Jika Anda hanya ingin mendeteksi satu transisi saja, tanpa menggunakan kerangka JS apa pun di sini adalah fungsi utilitas kecil yang nyaman:

function once = function(object,event,callback){
    var handle={};

    var eventNames=event.split(" ");

    var cbWrapper=function(){
        eventNames.forEach(function(e){
            object.removeEventListener(e,cbWrapper, false );
        });
        callback.apply(this,arguments);
    };

    eventNames.forEach(function(e){
        object.addEventListener(e,cbWrapper,false);
    });

    handle.cancel=function(){
        eventNames.forEach(function(e){
            object.removeEventListener(e,cbWrapper, false );
        });
    };

    return handle;
};

Pemakaian:

var handler = once(document.querySelector('#myElement'), 'transitionend', function(){
   //do something
});

maka jika Anda ingin membatalkan di beberapa titik Anda masih dapat melakukannya dengan

handler.cancel();

Ini bagus untuk penggunaan acara lainnya :)

OpherV
sumber