Rückruf beim CSS-Übergang

Antworten:

82

Ich weiß, dass Safari einen webkitTransitionEnd- Rückruf implementiert , den Sie mit dem Übergang direkt an das Element anhängen können.

Ihr Beispiel (in mehrere Zeilen umformatiert):

box.addEventListener( 
     'webkitTransitionEnd', 
     function( event ) { 
         alert( "Finished transition!" ); 
     }, false );
Doug Neiner
quelle
Gibt es dasselbe für andere Browser als das Webkit?
Meo
6
Ja, 'Transitionend' für Mozilla & 'oTransitionEnd' in Opera.
Qqryq
2
Was macht das Falsche am Ende?
Meo
@meo Es hat etwas mit dem thisElement im Rückruf zu tun . Aber es ist ein erforderlicher Parameter, also erfüllt es in diesem Fall nur die Anforderung.
Doug Neiner
8
@DougNeiner Das Falsche am Ende ist für useCaptureMode. Wenn ein Ereignis eintritt, gibt es zwei Phasen - die erste Phase ist der Erfassungsmodus, die zweite ist der Blasenmodus. Im Erfassungsmodus steigt das Ereignis vom Körperelement zum angegebenen Element ab. Es wechselt dann in den Blasenmodus, wo es das Gegenteil tut. Dieser letzte falsche Parameter gibt an, dass der Ereignis-Listener im Bubble-Modus auftreten soll. Eine Möglichkeit besteht darin, Ereignishandler anzuhängen, bevor sie im Blasenmodus benötigt werden. =) 37signals.com/svn/posts/…
Rybosom
103

Ja, wenn solche Dinge vom Browser unterstützt werden, wird ein Ereignis ausgelöst, wenn der Übergang abgeschlossen ist. Das tatsächliche Ereignis unterscheidet sich jedoch zwischen den Browsern:

  • Webkit-Browser (Chrome, Safari) verwenden webkitTransitionEnd
  • Firefox verwendet transitionend
  • IE9 + verwendet msTransitionEnd
  • Opera verwendet oTransitionEnd

Sie sollten sich jedoch bewusst sein, dass webkitTransitionEndnicht immer feuert! Dies hat mich mehrmals erwischt und scheint aufzutreten, wenn die Animation keine Auswirkung auf das Element hätte. Um dies zu umgehen, ist es sinnvoll, eine Zeitüberschreitung zu verwenden, um den Ereignishandler auszulösen, falls er nicht wie erwartet ausgelöst wurde. Ein Blog-Beitrag zu diesem Problem ist hier verfügbar: http://www.cuppadev.co.uk/the-trouble-with-css-transitions/ <- 500 Internal Server Error

In diesem Sinne tendiere ich dazu, dieses Ereignis in einem Codeabschnitt zu verwenden, der ein bisschen so aussieht:

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) 

Hinweis: Um den Endnamen des Übergangsereignisses zu erhalten, können Sie die Methode verwenden, die als Antwort in: Wie normalisiere ich CSS3-Übergangsfunktionen über Browser hinweg? .

Hinweis: Diese Frage bezieht sich auch auf: - CSS3-Übergangsereignisse

Mark Rhodes
quelle
2
Dies ist eine viel umfassendere Antwort als die akzeptierte. Warum ist das nicht mehr positiv bewertet?
Wes
Denken Sie daran, rufen Sie transitionEndedHandlerin transitionEnded(oder Änderung transitionEndedvon transitionEndedHandlerin addEventListenerund removeEventListenerund Call - transitionEndedin transitionEndedHandler)
Miquel
Danke @Miquel; Ich glaube, ich hatte es gerade benutzt, transitionEndedals ich es meinte transitionEndedHandler.
Mark Rhodes
Ich glaube, das Chromium-Problem hierfür ist hier zu finden: code.google.com/p/chromium/issues/detail?id=388082 Obwohl der letzte Kommentar (meiner Ansicht nach fälschlicherweise) es als Fehler und damit als Fehler abwertet ist derzeit als "wird nicht behoben" markiert.
Willster
Heutzutage sind keine anderen Namen mehr erforderlich. Caniuse.com/#feat=css-transitions
Juan Mendes
43

Ich verwende den folgenden Code, ist viel einfacher als zu versuchen zu erkennen, welches spezifische Endereignis ein Browser verwendet.

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

Wenn Sie Bootstrap verwenden, können Sie dies auch einfach tun

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

Dies liegt daran, dass sie Folgendes in bootstrap.js enthalten

+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
quelle
2
Dies ist langsamer, da jedes Mal, wenn das Ereignis eintritt, die gesamte Liste durchsucht werden muss, um festzustellen, ob es die richtige ist.
Phreakhead
3
@phreakhead Die Leistungen eines dieser Ansätze werden sehr ähnlich sein
Tom
6

Das jQuery.transit-Plugin , ein Plugin für CSS3-Transformationen und -Übergänge, kann Ihre CSS-Animationen über ein Skript aufrufen und Ihnen einen Rückruf geben.

Brian
quelle
5

Dies kann leicht mit der transitionendVeranstaltung erreicht werden, siehe Dokumentation hier. Ein einfaches Beispiel:

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
quelle
1
Dies ist heutzutage die richtige Antwort. Es sind keine Präfixe mehr erforderlich. caniuse.com/#feat=css-transitions
Juan Mendes