[英]How do I normalize CSS3 Transition functions across browsers?
Webkit's transition end event is called webkitTransitionEnd, Firefox is transitionEnd, opera is oTransitionEnd. Webkit的过渡结束事件称为webkitTransitionEnd,Firefox为transitionEnd,歌剧为oTransitionEnd。 What is a good way of tackling all of them in pure JS? 用纯JS解决所有问题的好方法是什么? Should I do browser sniffing? 我应该浏览器嗅探吗? or implement each one separately? 还是分别实施? Some other way that hasn't occurred to me? 我还没有发生过其他事情?
ie: 即:
//doing browser sniffing
var transitionend = (isSafari) ? "webkitTransitionEnd" : (isFirefox) ? "transitionEnd" : (isOpera) ? "oTransitionEnd";
element.addEventListener(transitionend, function(){
//do whatever
},false);
or 要么
// Assigning an event listener per browser
element.addEventListener("webkitTransitionEnd", fn);
element.addEventListener("oTransitionEnd", fn);
element.addEventListener("transitionEnd", fn);
function fn() {
//do whatever
}
There's a technique used in Modernizr, improved: 在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';
}
Then you can just call this function whenever you need the transition end event: 然后,只要需要过渡结束事件,就可以调用此函数:
var transitionEnd = transitionEndEventName();
element.addEventListener(transitionEnd, theFunctionToInvoke, false);
As per Matijs comment, the easiest way to detect transition events is with a library, jquery in this case: 根据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')
});
In library-less javascript it gets a bit verbose: 在无库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
}
Update 更新资料
The following is a cleaner way of doing it, and doesn't require modernizr 以下是更干净的方法,不需要modernizr
$(".myClass").one('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd',
function() {
//do something
});
Alternatively 或者
var transEndEventNames = {
'WebkitTransition': 'webkitTransitionEnd',
'MozTransition': 'transitionend',
'OTransition': 'oTransitionEnd otransitionend',
'msTransition': 'MSTransitionEnd',
'transition': 'transitionend'
}, transitionEnd = transEndEventNames[Modernizr.prefixed('transition')];
This is based on the code suggested by Modernizr, but with the extra event for newer versions of Opera. 这是基于Modernizr建议的代码,但具有适用于较新版本Opera的额外事件。
http://modernizr.com/docs/#prefixed http://modernizr.com/docs/#prefixed
If you use jQuery and Bootstrap $.support.transition.end
will return the right event for the current browser. 如果您使用jQuery和Bootstrap,则$.support.transition.end
将为当前浏览器返回正确的事件。
It is defined in Bootstrap and used in its animation callbacks , though the jQuery docs say not to rely on these properties: 它是在Bootstrap中定义的,并在其动画回调中使用 ,尽管jQuery文档说不要依赖这些属性:
Although some of these properties are documented below, they are not subject to a long deprecation/removal cycle and may be removed once internal jQuery code no longer needs them. 尽管下面记录了其中的某些属性,但它们不受较长的弃用/删除周期的限制,一旦内部jQuery代码不再需要它们即可将其删除。
http://api.jquery.com/jQuery.support/ http://api.jquery.com/jQuery.support/
As of 2015, this one-liner should do the deal (IE 10+, Chrome 1+, Safari 3.2+, FF 4+ and Opera 12+):- 从2015年起,这种单线模式就可以达成交易(IE 10 +,Chrome 1 +,Safari 3.2 +,FF 4+和Opera 12+):
var transEndEventName = ('WebkitTransition' in document.documentElement.style) ? 'webkitTransitionEnd' : 'transitionend'
Attaching the event listener is simple:- 附加事件监听器很简单:
element.addEventListener(transEndEventName , theFunctionToInvoke);
Here is a more cleaner way 这是一种更清洁的方法
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 closure makes sure you don't have to do this. 谷歌关闭确保您不必执行此操作。 If you have an element: 如果您有一个元素:
goog.events.listen(element, goog.events.EventType.TRANSITIONEND, function(event) {
// ... your code here
});
looking at the source of goog.events.eventtype.js, TRANSITIONEND is calculated by looking at the useragent: 查看goog.events.eventtype.js的源代码,可以通过查看useragent来计算TRANSITIONEND:
// 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 override: 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);
and usage like: 和用法如下:
$('myDiv').on('transitionend', function() { ... });
The second is the way to go. 第二是要走的路。 Only one of those events will fire in every browser, so you can set all of them and it'll work. 这些事件中只有一个会在每个浏览器中触发,因此您可以设置所有事件,它就会起作用。
I use code like this (with jQuery) 我使用这样的代码(使用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
}
That lets me use JS to add things by specifying vP concatentated with the property, and if it didn't hit a browser it just uses the standard. 这使我可以使用JS通过指定与该属性关联的vP来添加内容,如果它未在浏览器中运行,则仅使用标准。 The events lets me easily bind like so: 这些事件使我可以像这样轻松绑定:
object.bind(transitionEnd,function(){
callback();
});
Accepted answer is correct but you don't have to re-create that element again-and-again-and... 接受的答案是正确的,但是您不必一次又一次地重新创建该元素。
Build a global variable and add the function(s): 构建一个全局变量并添加函数:
(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));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.