Zdarzenie końcowe przejścia Webkit nazywa się webkitTransitionEnd, Firefox to przejścieEnd, opera to oTransitionEnd. Jaki jest dobry sposób radzenia sobie z nimi wszystkimi w czystym JS? Czy powinienem wąchać przeglądarkę? czy wdrożyć każdy z nich osobno? W inny sposób nie przyszło mi do głowy?
to znaczy:
//doing browser sniffing
var transitionend = (isSafari) ? "webkitTransitionEnd" : (isFirefox) ? "transitionEnd" : (isOpera) ? "oTransitionEnd";
element.addEventListener(transitionend, function(){
//do whatever
},false);
lub
// Assigning an event listener per browser
element.addEventListener("webkitTransitionEnd", fn);
element.addEventListener("oTransitionEnd", fn);
element.addEventListener("transitionEnd", fn);
function fn() {
//do whatever
}
javascript
css
css-transitions
dom-events
metoda działania
źródło
źródło
Odpowiedzi:
Jest technika używana w Modernizr, 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'; }
Następnie możesz po prostu wywołać tę funkcję, gdy potrzebujesz zdarzenia zakończenia przejścia:
var transitionEnd = transitionEndEventName(); element.addEventListener(transitionEnd, theFunctionToInvoke, false);
źródło
transition
itransitionend
wystarczy. Zobacz: caniuse.com/#search=transitionsundefined
?Zgodnie z komentarzem Matijsa, najłatwiejszym sposobem wykrycia 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 javascript bez biblioteki robi się trochę rozwlekły:
element.addEventListener('webkitTransitionEnd', callfunction, false); element.addEventListener('oTransitionEnd', callfunction, false); element.addEventListener('transitionend', callfunction, false); element.addEventListener('msTransitionEnd', callfunction, false); function callfunction() { //do whatever }
źródło
msTransitionend
nie jest tu potrzebny.Aktualizacja
Poniższy sposób jest bardziej przejrzysty 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
źródło
one
zamiaston
. To było takie oczywiste!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 wywołaniach zwrotnych animacji , chociaż dokumentacja jQuery mówi, że nie należy polegać na tych właściwościach:
źródło
Od 2015 r. Ta jednolinijka powinna załatwić sprawę (IE 10+, Chrome 1+, Safari 3.2+, FF 4+ i Opera 12 +): -
var transEndEventName = ('WebkitTransition' in document.documentElement.style) ? 'webkitTransitionEnd' : 'transitionend'
Dołączanie detektora zdarzeń jest proste: -
źródło
transitionend
nie jest w ogóle obsługiwany:var transEndEventName = ('WebkitTransition' in document.documentElement.style) ? 'webkitTransitionEnd' : ('transitionend' in document.documentElement.style) ? 'transitionend' : false;
A potem zrób prostą kontrolę:if(transEndEventName) element.addEventlistener(transEndEventName, theFunctionToInvoke)
Drugi sposób to droga. Tylko jedno z tych zdarzeń zostanie uruchomione w każdej przeglądarce, więc możesz ustawić je wszystkie i zadziała.
źródło
Oto bardziej przejrzysty 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"; }
źródło
zamknięcie Google zapewnia, ż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.events.eventtype.js, TRANSITIONEND oblicza się, 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'),
źródło
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 przez określenie vP połączonego z właściwością, a jeśli nie trafił on w przeglądarkę, po prostu używa standardu. Wydarzenia pozwalają mi łatwo związać w ten sposób:
object.bind(transitionEnd,function(){ callback(); });
źródło
object.bind('transitionend oTransitionEnd webkitTransitionEnd', function() { // callback } );
transitionend
nieTransitionEnd
.nadpisanie jquery:
(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 zastosowanie takie jak:
$('myDiv').on('transitionend', function() { ... });
źródło
Zaakceptowana odpowiedź jest poprawna, ale nie musisz ponownie tworzyć tego elementu raz po raz i ...
Zbuduj zmienną globalną i dodaj funkcje:
(function(myLib, $, window, document, undefined){ /** * @summary * Returns the browser's supported animation end event type. * @desc * @see {@link https://jonsuh.com/blog/detect-the-end-of-css-animations-and-transitions-with-javascript/} * @function myLib.getAnimationEndType * @return {string} The animation end event type */ (function(){ var type; myLib.getAnimationEndType = function(){ if(!type) type = callback(); return type; function callback(){ var t, el = document.createElement("fakeelement"); var animations = { "animation" : "animationend", "OAnimation" : "oAnimationEnd", "MozAnimation" : "animationend", "WebkitAnimation": "webkitAnimationEnd" } for (t in animations){ if (el.style[t] !== undefined){ return animations[t]; } } } } }()); /** * @summary * Returns the browser's supported transition end event type. * @desc * @see {@link https://jonsuh.com/blog/detect-the-end-of-css-animations-and-transitions-with-javascript/} * @function myLib.getTransitionEndType * @return {string} The transition end event type */ (function(){ var type; myLib.getTransitionEndType = function(){ if(!type) type = callback(); return type; function callback(){ var t, el = document.createElement("fakeelement"); var transitions = { "transition" : "transitionend", "OTransition" : "oTransitionEnd", "MozTransition" : "transitionend", "WebkitTransition": "webkitTransitionEnd" } for (t in transitions){ if (el.style[t] !== undefined){ return transitions[t]; } } } } }()); }(window.myLib = window.myLib || {}, jQuery, window, document));
źródło