Jak znormalizować funkcje przejścia CSS3 między przeglądarkami?

Zdarzenie przejścia Webkit nazywa się webkitTransitionEnd, Firefox to transitionEnd, opera to oTransitionEnd. Jaki jest dobry sposób na walkę z nimi wszystkimi w czystym JS? Czy powinienem zrobić sniffing przeglądarki? lub zaimplementować każdy z nich osobno? Jakiś inny sposób, który mi się nie przydarzył?

Ie:

//doing browser sniffing
var transitionend = (isSafari) ? "webkitTransitionEnd" : (isFirefox) ? "transitionEnd" : (isOpera) ? "oTransitionEnd";

element.addEventListener(transitionend, function(){
  //do whatever
},false);

Lub

//asigning an event listener per browser
element.addEventListener(webkitTransitionEnd, function(){callfunction()},false);
element.addEventListener(oTransitionEnd, function(){callfunction()},false);
element.addEventListener(transitionEnd, function(){callfunction()},false);

function callfunction() {
   //do whatever
}
Author: BoltClock, 2011-02-17

10 answers

Jest technika używana w Modernizrze, ulepszona:

function transitionEndEventName () {
    var i,
        undefined,
        el = document.createElement('div'),
        transitions = {
            'transition':'transitionend',
            'OTransition':'otransitionend',  // oTransitionEnd in very old Opera
            'MozTransition':'transitionend',
            'WebkitTransition':'webkitTransitionEnd'
        };

    for (i in transitions) {
        if (transitions.hasOwnProperty(i) && el.style[i] !== undefined) {
            return transitions[i];
        }
    }

    //TODO: throw 'TransitionEnd event is not supported in this browser'; 
}

Wtedy możesz po prostu wywołać tę funkcję, gdy potrzebujesz zdarzenia końca przejścia:

var transitionEnd = transitionEndEventName();
element.addEventListener(transitionEnd, theFunctionToInvoke, false);
 160
Author: webinista,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-27 18:02:09

Zgodnie z komentarzem Matijs, najprostszym sposobem na wykrycie zdarzeń przejścia jest biblioteka, w tym przypadku jquery:

$("div").bind("webkitTransitionEnd.done oTransitionEnd.done otransitionend.done transitionend.done msTransitionEnd.done", function(){
  // Unlisten called events by namespace,
  // to prevent multiple event calls. (See comment)
  // By the way, .done can be anything you like ;)
  $(this).off('.done')
});

W JavaScripcie bez biblioteki robi się trochę gadatliwy:

element.addEventListener('webkitTransitionEnd', callfunction, false);
element.addEventListener('oTransitionEnd', callfunction, false);
element.addEventListener('transitionend', callfunction, false);
element.addEventListener('msTransitionEnd', callfunction, false);

function callfunction() {
   //do whatever
}
 21
Author: Duopixel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-30 14:45:45

Jeśli używasz jQuery i Bootstrap $.support.transition.end zwróci odpowiednie zdarzenie dla bieżącej przeglądarki.

Jest zdefiniowany w Bootstrap i używany w jego wywołaniach animacji , chociaż dokumenty jQuery mówią, aby nie polegać na tych właściwościach:

Chociaż niektóre z tych właściwości są udokumentowane poniżej, nie podlegają one dłuższemu cyklowi deprecacji/usuwania i mogą zostać usunięte, gdy wewnętrzny kod jQuery nie będzie ich już potrzebował.

Http://api.jquery.com/jQuery.support/

 8
Author: meleyal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-04 15:09:04

Update

Poniższy sposób jest czystszy i nie wymaga modernizacji

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

Alternatywnie

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

Jest to oparte na kodzie sugerowanym przez Modernizr, ale z dodatkowym zdarzeniem dla nowszych wersji Opery.

Http://modernizr.com/docs/#prefixed

 7
Author: Tom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-14 12:07:00

W 2015 roku ta jedna linijka powinna wykonać transakcję (IE 10+, Chrome 1+, Safari 3.2+, FF 4+ i Opera 12+): -

var transEndEventName = ('WebkitTransition' in document.documentElement.style) ? 'webkitTransitionEnd' : 'transitionend'
Dołączenie detektora zdarzeń jest proste: -
element.addEventListener(transEndEventName , theFunctionToInvoke);
 6
Author: Salman Abbas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-12 15:20:50

Tutaj jest bardziej czystszy sposób

 function transitionEvent() {
      // Create a fake element
      var el = document.createElement("div");

      if(el.style.OTransition) return "oTransitionEnd";
      if(el.style.WebkitTransition) return "webkitTransitionEnd";
      return "transitionend";
    }
 1
Author: Nicholas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-26 19:58:22

Druga to droga do wyjścia. Tylko jedno z tych zdarzeń zostanie uruchomione w każdej przeglądarce, więc możesz ustawić je wszystkie i będzie działać.

 0
Author: Lea Verou,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-17 11:23:40

Zamknięcie Google sprawia, że nie musisz tego robić. Jeśli masz element:

goog.events.listen(element, goog.events.EventType.TRANSITIONEND, function(event) {
  // ... your code here
});

Patrząc na źródło goog.wydarzenia.typ zdarzenia.js, TRANSITIONEND jest obliczany patrząc na useragent:

// CSS transition events. Based on the browser support described at:
  // https://developer.mozilla.org/en/css/css_transitions#Browser_compatibility
  TRANSITIONEND: goog.userAgent.WEBKIT ? 'webkitTransitionEnd' :
      (goog.userAgent.OPERA ? 'oTransitionEnd' : 'transitionend'),
 0
Author: Joe Heyming,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-28 18:53:51

Używam takiego kodu (z jQuery)

var vP = "";
var transitionEnd = "transitionend";
if ($.browser.webkit) {
    vP = "-webkit-";
    transitionEnd = "webkitTransitionEnd";
} else if ($.browser.msie) {
    vP = "-ms-";
} else if ($.browser.mozilla) {
    vP = "-moz-";
} else if ($.browser.opera) {
    vP = "-o-";
    transitionEnd = "otransitionend"; //oTransitionEnd for very old Opera
}

To pozwala mi używać JS do dodawania rzeczy, określając VP konkatentowane z właściwością, a jeśli nie trafiło w przeglądarkę, to po prostu używa standardu. Wydarzenia pozwalają mi łatwo związać TAK:

object.bind(transitionEnd,function(){
    callback();
});
 0
Author: Rich Bradshaw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-27 17:52:32

JQuery override:

(function ($) {
  var oldOn = $.fn.on;

  $.fn.on = function (types, selector, data, fn, /*INTERNAL*/ one) {
    if (types === 'transitionend') {
      types = 'transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd';
    }

    return oldOn.call(this, types, selector, data, fn, one);
  };
})(jQuery);

I użycie jak:

$('myDiv').on('transitionend', function() { ... });
 0
Author: Are Butuv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-12 15:44:57