Как нормализовать функции перехода CSS3 между браузерами?
событие конца перехода Webkit называется webkitTransitionEnd, Firefox-transitionEnd, opera-oTransitionEnd. Каков хороший способ решения всех из них в чистом JS? Должен ли я делать браузер нюхать? или реализовать каждый из них отдельно? Каким-то другим способом, который мне не приходил в голову?
ie:
//doing browser sniffing
var transitionend = (isSafari) ? "webkitTransitionEnd" : (isFirefox) ? "transitionEnd" : (isOpera) ? "oTransitionEnd";
element.addEventListener(transitionend, function(){
//do whatever
},false);
или
//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
}
10 ответов:
есть техника, используемая в Modernizr, улучшенная:
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'; }тогда вы можете просто вызвать эту функцию всякий раз, когда вам нужно событие конца перехода:
var transitionEnd = transitionEndEventName(); element.addEventListener(transitionEnd, theFunctionToInvoke, false);
согласно комментарию Matijs, самый простой способ обнаружения событий перехода - это библиотека, 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') });в JavaScript без библиотеки он становится немного подробным:
element.addEventListener('webkitTransitionEnd', callfunction, false); element.addEventListener('oTransitionEnd', callfunction, false); element.addEventListener('transitionend', callfunction, false); element.addEventListener('msTransitionEnd', callfunction, false); function callfunction() { //do whatever }
Если вы используете jQuery и Bootstrap
$.support.transition.endвернет правильное событие для текущего браузера.Это определено в Bootstrap и в его анимация обратных вызовов, хотя документы jQuery говорят, что не следует полагаться на эти свойства:
хотя некоторые из этих свойств описаны ниже, они не подвержены длительному циклу устаревания/удаления и могут быть удалены, как только внутренний код jQuery больше не нуждается в них.
обновление
ниже приведен более чистый способ сделать это, и не требует модернизации
$(".myClass").one('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd', function() { //do something });
как вариант
var transEndEventNames = { 'WebkitTransition': 'webkitTransitionEnd', 'MozTransition': 'transitionend', 'OTransition': 'oTransitionEnd otransitionend', 'msTransition': 'MSTransitionEnd', 'transition': 'transitionend' }, transitionEnd = transEndEventNames[Modernizr.prefixed('transition')];это основано на коде, предложенном Modernizr, но с дополнительным событием для более новых версий Opera.
С 2015 года этот однострочный лайнер должен делать сделку (т. е. 10+, Chrome 1+, Safari 3.2+, FF 4+ и Opera 12+): -
var transEndEventName = ('WebkitTransition' in document.documentElement.style) ? 'webkitTransitionEnd' : 'transitionend'прикрепление прослушивателя событий просто: -
element.addEventListener(transEndEventName , theFunctionToInvoke);
вот более чистый способ
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"; }
второй путь. Только одно из этих событий будет срабатывать в каждом браузере, так что вы можете установить все из них, и это будет работать.
закрытие google гарантирует, что вам не нужно этого делать. Если у вас есть элемент:
goog.events.listen(element, goog.events.EventType.TRANSITIONEND, function(event) { // ... your code here });глядя на источник goog.события.тип события.js, TRANSITIONEND вычисляется, глядя на 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'),
Я использую такой код (с помощью 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 }это позволяет мне использовать JS для добавления вещей, указав VP, объединенный со свойством, и если он не попал в браузер, он просто использует стандарт. События позволяет мне легко связать так:
object.bind(transitionEnd,function(){ callback(); });
переопределение 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);и использование как:
$('myDiv').on('transitionend', function() { ... });
Comments