Как нормализовать функции перехода CSS3 в разных браузерах? - PullRequest
88 голосов
/ 17 февраля 2011

Событие окончания перехода Webkit называется webkitTransitionEnd, Firefox - это transitionEnd, опера - это oTransitionEnd.Что является хорошим способом решения всех из них в чистом JS?Должен ли я делать анализ браузера?или реализовать каждый по отдельности?Какой-то другой способ, который не произошел со мной?

, т.е.

Ответы [ 10 ]

163 голосов
/ 01 февраля 2012

В 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);
22 голосов
/ 13 октября 2011

Согласно комментарию Матейса, самый простой способ обнаружить события перехода - это использовать библиотеку, в данном случае 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
}
8 голосов
/ 11 марта 2013

Если вы используете jQuery и Bootstrap, $.support.transition.end вернет правильное событие для текущего браузера.

Он определен в Bootstrap и используется в его анимационных обратных вызовах , хотя в документах jQuery сказано не полагаться на эти свойства:

Хотя некоторые из этих свойств описаны ниже, они не подлежат длительному циклу устаревания / удаления и могут быть удалены, когда внутренний код jQuery больше не нуждается в них.

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

8 голосов
/ 27 ноября 2012

Обновление

Следующее является более чистым способом, и не требует modernizr

$(".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.

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

6 голосов
/ 11 апреля 2015

Начиная с 2015 года этот однострочный контракт должен заключать сделку (IE 10+, Chrome 1+, Safari 3.2+, FF 4+ и Opera 12+): -

var transEndEventName = ('WebkitTransition' in document.documentElement.style) ? 'webkitTransitionEnd' : 'transitionend'

Присоединить прослушиватель событий просто: -

element.addEventListener(transEndEventName , theFunctionToInvoke);
1 голос
/ 26 марта 2017

Вот более чистый способ

 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";
    }
0 голосов
/ 12 августа 2016

Переопределение 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() { ... });
0 голосов
/ 28 марта 2014

закрытие Google гарантирует, что вам не нужно это делать. Если у вас есть элемент:

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

Если посмотреть на источник goog.events.eventtype.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'),
0 голосов
/ 31 марта 2011

Я использую такой код (с 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();
});
0 голосов
/ 17 февраля 2011

Второй путь. Только одно из этих событий будет срабатывать в каждом браузере, так что вы можете установить их все, и оно будет работать.

...