Callback przy przejściu CSS


Odpowiedzi:


82

Wiem, że Safari implementuje wywołanie zwrotne webkitTransitionEnd , które możesz dołączyć bezpośrednio do elementu z przejściem.

Ich przykład (ponownie sformatowany do wielu wierszy):

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

czy jest to samo dla innej przeglądarki niż webkit?
meo,

6
tak, „przejście na koniec” dla Mozilli i „oTransitionEnd” w Operze.
qqryq

2
co robi fałsz na końcu?
meo

@meo Ma to coś wspólnego z thiselementem wewnątrz wywołania zwrotnego. Ale jest to wymagany parametr, więc w tym przypadku spełnia on tylko wymaganie.
Doug Neiner

8
@DougNeiner Fałsz na końcu jest dla useCaptureMode. Kiedy zdarzenie ma miejsce, są dwie fazy - pierwsza faza to tryb przechwytywania, druga to tryb bąbelkowy. W trybie przechwytywania zdarzenie schodzi z elementu body do określonego elementu. Następnie przechodzi w tryb bąbelkowy, w którym działa odwrotnie. Ten ostatni fałszywy parametr określa, że ​​detektor zdarzeń ma działać w trybie bąbelkowym. Jednym z zastosowań tego jest dołączanie programów obsługi zdarzeń tuż przed ich użyciem w trybie bąbelkowym. =) 37signals.com/svn/posts/…
rybosome

103

Tak, jeśli takie rzeczy są obsługiwane przez przeglądarkę, to po zakończeniu przejścia wyzwalane jest zdarzenie. Faktyczne zdarzenie różni się jednak w zależności od przeglądarki:

  • Korzystanie z przeglądarek Webkit (Chrome, Safari) webkitTransitionEnd
  • Firefox używa transitionend
  • IE9 + używa msTransitionEnd
  • Opera używa oTransitionEnd

Należy jednak pamiętać, że webkitTransitionEndnie zawsze strzela! Przyłapało mnie to wiele razy i wydaje się, że ma miejsce, gdyby animacja nie miała wpływu na element. Aby obejść ten problem, warto użyć limitu czasu do uruchomienia procedury obsługi zdarzeń w przypadku, gdy nie została ona wyzwolona zgodnie z oczekiwaniami. Wpis na blogu dotyczący tego problemu jest dostępny tutaj: http://www.cuppadev.co.uk/the-trouble-with-css-transitions/ <- 500 Wewnętrzny błąd serwera

Mając to na uwadze, zwykle używam tego zdarzenia w kawałku kodu, który wygląda trochę tak:

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) 

Uwaga: aby uzyskać nazwę końca zdarzenia przejścia, możesz użyć metody opublikowanej jako odpowiedź w: Jak znormalizować funkcje przejścia CSS3 w różnych przeglądarkach? .

Uwaga: to pytanie dotyczy również: - zdarzeń przejścia CSS3


2
To znacznie pełniejsza odpowiedź niż ta przyjęta. Dlaczego nie jest to bardziej przychylne.
Wes

Pamiętaj, aby połączyć transitionEndedHandlersię transitionEnded(lub zmiana transitionEndedprzez transitionEndedHandlerw addEventListeneri removeEventListenera rozmowa transitionEndedw transitionEndedHandler)
Miquel

Dzięki @Miquel; myślę, że właśnie użyłem, transitionEndedkiedy miałem na myśli transitionEndedHandler.
Mark Rhodes

Wydaje mi się, że problem z Chromium w tym zakresie można znaleźć tutaj: code.google.com/p/chromium/issues/detail?id=388082 Chociaż ostatni komentarz wydaje się (moim zdaniem błędnie) zdyskontować go jako błąd i dlatego jest obecnie oznaczony jako „nie zostanie naprawiony”.
Willster

Obecnie nie ma potrzeby używania różnych nazw caniuse.com/#feat=css-transitions
Juan Mendes

43

Używam następującego kodu, jest znacznie prostszy niż próba wykrycia, którego konkretnego zdarzenia końcowego używa przeglądarka.

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

Alternatywnie, jeśli używasz bootstrap, możesz po prostu to zrobić

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

Dzieje się tak, ponieważ zawierają one następujące elementy w pliku 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
Jest to wolniejsze, ponieważ musi przeszukiwać całą listę za każdym razem, gdy zdarzenie ma miejsce, aby sprawdzić, czy jest to właściwe.
phreakhead

3
@phreakhead Wyniki każdego z tych podejść będą bardzo podobne
Tom


5

Można to łatwo osiągnąć dzięki transitionendwydarzeniu, patrz dokumentacja tutaj Prosty przykład:

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
To jest obecnie poprawna odpowiedź, nie ma już potrzeby stosowania przedrostków. caniuse.com/#feat=css-transitions
Juan Mendes
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.