Eventi di transizione CSS3


Risposte:


210

Bozza transizioni CSS W3C

Il completamento di una transizione CSS genera un evento DOM corrispondente. Viene generato un evento per ogni proprietà che subisce una transizione. Ciò consente a uno sviluppatore di contenuti di eseguire azioni che si sincronizzano con il completamento di una transizione.


Webkit

Per determinare quando una transizione viene completata, impostare una funzione di listener di eventi JavaScript per l'evento DOM che viene inviato al termine di una transizione. L'evento è un'istanza di WebKitTransitionEvent e il suo tipo è webkitTransitionEnd.

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

Mozilla

C'è un singolo evento che viene generato al completamento delle transizioni. In Firefox, l'evento è transitionend, in Opera oTransitionEnd, e in WebKit lo è webkitTransitionEnd.

musica lirica

È disponibile un tipo di evento di transizione. L' oTransitionEndevento si verifica al completamento della transizione.

Internet Explorer

L' transitionendevento si verifica al completamento della transizione. Se la transizione viene rimossa prima del completamento, l'evento non si attiverà.


Stack Overflow: come posso normalizzare le funzioni di transizione CSS3 tra i browser?


3
Si noti che l'evento si chiama "transizione" in Firefox e "oTransitionEnd" in Opera
Andreas Köberle,

8
Nessuno ha menzionato nulla sulla parte di inizio della transizione della domanda. Non è possibile registrare un gestore eventi da attivare prima che inizi la transizione?
Tyler,

Esiste ora un modo standard per raggiungere questo obiettivo? Sembra che 2 anni siano tanti! Le cose sono probabilmente cambiate.
Lieve Fuzz,

@tyler non so come aggirare la mancanza di transizioni-inizio.
Assapora Lucic

@La domanda StackOverflow legata a Fuzz ha una soluzione interessante.
Assapora Lucic

73

Aggiornare

Tutti i browser moderni ora supportano l'evento non risolto:

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

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


Stavo usando l'approccio dato da Pete, tuttavia ora ho iniziato a usare quanto segue

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

In alternativa, se usi bootstrap, puoi semplicemente farlo

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

Questo perché includono quanto segue in 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);

Nota che includono anche una funzione emulateTransitionEnd che potrebbe essere necessaria per garantire che si verifichi sempre un callback.

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

Tieni presente che a volte questo evento non si attiva, di solito nel caso in cui le proprietà non cambiano o una vernice non viene attivata. Per essere sicuri di ricevere sempre una richiamata, impostiamo un timeout che attiverà manualmente l'evento.

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


3
Non puoi fare qualcosa del genere. In alcuni casi callbaack verrà attivato più di una volta.
sebastian,

11
Nei browser che mantengono sia il prefisso che il normale nome dell'evento. Puoi aggirare il problema utilizzando .one invece di
.on

61

Tutti i browser moderni ora supportano l'evento non risolto:

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

Funziona con le ultime versioni di Chrome, Firefox e Safari. Anche IE10 +.


16

In Opera 12 quando esegui il bind utilizzando il semplice JavaScript, 'oTransitionEnd' funzionerà:

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

tuttavia se esegui il binding tramite jQuery, devi utilizzare "otransitionend"

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

Nel caso in cui tu stia usando Modernizr o bootstrap-transizione.js puoi semplicemente fare una modifica:

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

Puoi trovare alcune informazioni anche qui http://www.ianlunn.co.uk/blog/articles/opera-12-otransitionend-bugs-and-workarounds/


6

Solo per divertimento, non farlo!

$.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');
});

3

Se vuoi semplicemente rilevare solo una singola estremità di transizione, senza usare alcun framework JS ecco una piccola funzione di utilità:

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

Uso:

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

quindi se desideri annullare a un certo punto puoi comunque farlo

handler.cancel();

È buono anche per altri utilizzi di eventi :)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.