Richiamata sulla transizione CSS


Risposte:


82

So che Safari implementa un callback webkitTransitionEnd che puoi allegare direttamente all'elemento con la transizione.

Il loro esempio (riformattato su più righe):

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

c'è la stessa cosa per altri browser quindi webkit?
meo

6
sì, "Transitionend" per Mozilla e "oTransitionEnd" in Opera.
qqryq

2
cosa fa il falso alla fine?
meo

@meo Ha qualcosa a che fare con l' thiselemento all'interno del callback. Ma è un parametro obbligatorio, quindi in questo caso soddisfa solo il requisito.
Doug Neiner

8
@DougNeiner Il falso alla fine è per useCaptureMode. Quando si verifica un evento, ci sono due fasi: la prima fase è la modalità di acquisizione, la seconda è la modalità bolla. In modalità di acquisizione, l'evento discende dall'elemento body all'elemento specificato. Quindi entra in modalità bolla, dove fa il contrario. Quell'ultimo parametro falso specifica che vuoi che il listener di eventi si verifichi in modalità bolla. Un utilizzo di questo è collegare i gestori di eventi appena prima che siano necessari in modalità bolla. =) 37signals.com/svn/posts/…
rybosome

103

Sì, se queste cose sono supportate dal browser, viene attivato un evento al termine della transizione. L'evento reale, tuttavia, differisce tra i browser:

  • Utilizzo dei browser Webkit (Chrome, Safari) webkitTransitionEnd
  • Firefox utilizza transitionend
  • IE9 + utilizza msTransitionEnd
  • Opera utilizza oTransitionEnd

Tuttavia dovresti essere consapevole che webkitTransitionEndnon sempre spara! Questo mi ha colto diverse volte e sembra che si verifichi se l'animazione non ha alcun effetto sull'elemento. Per aggirare questo problema, ha senso utilizzare un timeout per attivare il gestore di eventi nel caso in cui non sia stato attivato come previsto. Un post sul blog su questo problema è disponibile qui: http://www.cuppadev.co.uk/the-trouble-with-css-transitions/ <- 500 Internal Server Error

Con questo in mente, tendo a usare questo evento in un pezzo di codice che assomiglia un po 'a questo:

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) 

Nota: per ottenere il nome dell'evento di transizione è possibile utilizzare il metodo pubblicato come risposta in: Come normalizzo le funzioni di transizione CSS3 nei browser? .

Nota: questa domanda è anche correlata a: - Eventi di transizione CSS3


2
Questa è una risposta molto più completa di quella accettata. Perché questo non è più votato.
Wes

Ricordarsi di chiamare transitionEndedHandlera transitionEnded(o il cambiamento transitionEndedda transitionEndedHandlerin addEventListenere removeEventListenere la chiamata transitionEndedin transitionEndedHandler)
Miquel

Grazie @Miquel; penso di aver usato solo transitionEndedquando intendevo transitionEndedHandler.
Mark Rhodes

Credo che il problema di Chromium per questo possa essere trovato qui: code.google.com/p/chromium/issues/detail?id=388082 Anche se, l'ultimo commento sembra (erroneamente a mio avviso) scartarlo come un bug e quindi è attualmente contrassegnato come "non risolverà".
Willster,

Non c'è bisogno di nomi diversi al giorno d'
Juan Mendes

43

Sto usando il seguente codice, è molto più semplice che cercare di rilevare quale specifico evento finale utilizza un browser.

$(".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 (  ._.)
  }

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

2
Questo è più lento perché deve cercare nell'intero elenco ogni volta che si verifica l'evento per vedere se è quello corretto.
phreakhead

3
@phreakhead Le prestazioni di uno qualsiasi di questi approcci saranno molto simili
Tom

6

Il plugin jQuery.transit , un plugin per trasformazioni e transizioni CSS3, può richiamare le tue animazioni CSS dallo script e darti una richiamata.


5

Ciò può essere facilmente ottenuto con l' transitionendevento, vedere la documentazione qui Un semplice esempio:

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>


1
Questa è la risposta corretta al giorno d'oggi, non è più necessario avere prefissi. caniuse.com/#feat=css-transitions
Juan Mendes
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.