web-dev-qa-db-fra.com

Comment normaliser les fonctions de transition CSS3 entre les navigateurs?

L'événement de fin de transition de Webkit est appelé webkitTransitionEnd, Firefox est transitionEnd, opera est oTransitionEnd. Quelle est une bonne façon de les aborder tous en JS pur? Dois-je faire un sniffing du navigateur? Ou les implémenter séparément) ? Une autre façon qui ne m'est pas venue à l'esprit?

c'est à dire:

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

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

ou

// Assigning an event listener per browser
element.addEventListener("webkitTransitionEnd", fn);
element.addEventListener("oTransitionEnd", fn);
element.addEventListener("transitionEnd", fn);

function fn() {
   //do whatever
}
88
methodofaction

Il y a une technique utilisée dans Modernizr, améliorée:

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'; 
}

Ensuite, vous pouvez simplement appeler cette fonction chaque fois que vous avez besoin de l'événement de fin de transition:

var transitionEnd = transitionEndEventName();
element.addEventListener(transitionEnd, theFunctionToInvoke, false);
164
webinista

Selon le commentaire de Matijs, la manière la plus simple de détecter les événements de transition est d'utiliser une bibliothèque, jquery dans ce cas:

$("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')
});

En javascript sans bibliothèque, il devient un peu détaillé:

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

function callfunction() {
   //do whatever
}
22
methodofaction

Mise à jour

Ce qui suit est une façon plus propre de le faire et ne nécessite pas de modernisation

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

Alternativement

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

Ceci est basé sur le code suggéré par Modernizr, mais avec l'événement supplémentaire pour les nouvelles versions d'Opera.

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

8
Tom

Si vous utilisez jQuery et Bootstrap $.support.transition.end renverra le bon événement pour le navigateur actuel.

Il est défini dans Bootstrap et utilisé dans ses rappels d'animation , bien que les documents jQuery disent de ne pas s'appuyer sur ces propriétés:

Bien que certaines de ces propriétés soient documentées ci-dessous, elles ne sont pas soumises à un long cycle de dépréciation/suppression et peuvent être supprimées une fois que le code jQuery interne n'en a plus besoin.

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

8
meleyal

À partir de 2015, ce one-liner devrait faire l'affaire (IE 10+, Chrome 1+, Safari 3.2+, FF 4+ et Opera 12+) ): -

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

Attacher l'écouteur d'événement est simple: -

element.addEventListener(transEndEventName , theFunctionToInvoke);
6
Salman for Hire

Voici une façon plus propre

 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
Nicholas

J'utilise du code comme celui-ci (avec 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
}

Cela me permet d'utiliser JS pour ajouter des choses en spécifiant vP concaténé avec la propriété, et s'il ne frappe pas un navigateur, il utilise simplement la norme. Les événements me permettent de lier facilement comme ceci:

object.bind(transitionEnd,function(){
    callback();
});
0
Rich Bradshaw

remplacement 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);

et une utilisation comme:

$('myDiv').on('transitionend', function() { ... });
0
Are Butuv

La seconde est la voie à suivre. Un seul de ces événements se déclenchera dans chaque navigateur, vous pouvez donc les définir tous et cela fonctionnera.

0
Lea Verou

la fermeture de google vous évite de le faire. Si vous avez un élément:

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

en regardant la source de goog.events.eventtype.js, TRANSITIONEND est calculé en regardant l'agent utilisateur:

// 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
Joe Heyming