我如何正常化跨浏览器的CSS3转换function?

Webkit的转换结束事件叫做webkitTransitionEnd,Firefox是transitionEnd,opera是oTransitionEnd。 在纯JS中处理所有这些问题的好方法是什么? 我应该做浏览器嗅探吗? 或分别实施每一个? 还有一些没有发生在我身上的方式?

即:

//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 } 

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 } 

更新

以下是一个更干净的方式,并不需要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')]; 

这是基于Modernizrbuild议的代码,但与更新版本的Opera的额外事件。

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

如果您使用jQuery和Bootstrap $.support.transition.end将返回当前浏览器的正确事件。

它在Bootstrap中定义,并在其animationcallback中使用 ,尽pipejQuery文档说不依赖于这些属性:

尽pipe下面列出了这些属性中的一些,但是它们不会经历漫长的弃用/移除周期,并且一旦内部jQuery代码不再需要它们,就可能被删除。

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

截至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); 

这是一个更清洁的方式

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

第二是要走的路。 只有其中一个事件会在每个浏览器中触发,所以您可以设置所有这些事件,它将工作。

谷歌closures确保你不必这样做。 如果你有一个元素:

 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'), 

我使用这样的代码(与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() { ... });