检测对 JavaScript 转换的支持
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10888211/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Detect support for transition with JavaScript
提问by user1087110
I want to serve different javascript files depending on if browser supports CSS3 transition or not. Is there a better way to detect transition support than my code below?
我想根据浏览器是否支持 CSS3 转换来提供不同的 javascript 文件。有没有比我下面的代码更好的方法来检测转换支持?
window.onload = function () {
var b = document.body.style;
if(b.MozTransition=='' || b.WebkitTransition=='' || b.OTransition=='' || b.transition=='') {
alert('supported');
} else {
alert('NOT supported')
}
}
采纳答案by Blazemonger
Modernizr will detect this for you. Use this linkto create a custom download build that only contains CSS3 2D and/or 3D transitions.
Modernizr 会为您检测到这一点。使用此链接创建仅包含 CSS3 2D 和/或 3D 过渡的自定义下载版本。
Once it's run, you can either test for the csstransitions
class on the html
tag (CSS), or in JavaScript, test if Modernizr.csstransitions
is true
.
运行后,您可以测试标签csstransitions
上的类html
(CSS),或者在 JavaScript 中测试是否Modernizr.csstransitions
为true
。
More docs: http://modernizr.com/docs/#csstransitions
回答by Daniel
I also think including Modernizr is an overkill. The function below should work for any feature.
我也认为包括 Modernizr 是一种矫枉过正。下面的函数应该适用于任何功能。
function detectCSSFeature(featurename){
var feature = false,
domPrefixes = 'Webkit Moz ms O'.split(' '),
elm = document.createElement('div'),
featurenameCapital = null;
featurename = featurename.toLowerCase();
if( elm.style[featurename] !== undefined ) { feature = true; }
if( feature === false ) {
featurenameCapital = featurename.charAt(0).toUpperCase() + featurename.substr(1);
for( var i = 0; i < domPrefixes.length; i++ ) {
if( elm.style[domPrefixes[i] + featurenameCapital ] !== undefined ) {
feature = true;
break;
}
}
}
return feature;
}
var hasCssTransitionSupport = detectCSSFeature("transition");
Inspired by https://developer.mozilla.org/en-US/docs/CSS/Tutorials/Using_CSS_animations/Detecting_CSS_animation_support
回答by Dan
Here is another testing code. Maybe it is an overkill, but the function tries to set the CSS property to DOM object and then read back from it.
这是另一个测试代码。也许这是一种矫枉过正,但该函数尝试将 CSS 属性设置为 DOM 对象,然后从中读取。
Never tested this code on large amount of exotic browsers, but it is safer than just checking for the CSS property availability. Ah, yes, it can distinguish 2D transform support from 3D transform support! Just pass CSS property values you want to test!
从未在大量异国浏览器上测试此代码,但它比仅检查 CSS 属性可用性更安全。啊,是的,它可以区分 2D 变换支持和 3D 变换支持!只需传递您要测试的 CSS 属性值即可!
The plus of this code is that it detects the vendor prefix supported (if any). Possible return values:
此代码的优点是它检测支持的供应商前缀(如果有)。可能的返回值:
false
, when feature unsupported, or
false
,当功能不受支持时,或
{
vendor: 'moz',
cssStyle: '-moz-transition',
jsStyle: 'MozTransition'
}
when feature supported
当功能支持时
/**
* Test for CSS3 feature support. Single-word properties only by now.
* This function is not generic, but it works well for transition and transform at least
*/
testCSSSupport: function (feature, cssTestValue/* optional for transition and transform */) {
var testDiv,
featureCapital = feature.charAt(0).toUpperCase() + feature.substr(1),
vendors = ['', 'webkit', 'moz', 'ms', 'o'],
jsPrefixes = ['', 'Webkit', 'Moz', 'ms', 'O'],
defaultTestValues = {
transition: 'left 2s ease 1s',
transform: 'rotateX(-180deg) translateZ(.5em) scale(0.5)'
// This will test for 3D transform support
// Use other values if you need to test for 2D support only
},
testFunctions = {
transition: function (jsProperty, computed) {
return computed[jsProperty + 'Delay'] === '1s' && computed[jsProperty + 'Duration'] === '2s' && computed[jsProperty + 'Property'] === 'left';
},
transform: function (jsProperty, computed) {
return computed[jsProperty].substr(0, 9) === 'matrix3d(';
}
};
/* test given vendor prefix */
function isStyleSupported(feature, jsPrefixedProperty) {
if (jsPrefixedProperty in testDiv.style) {
var testVal = cssTestValue || defaultTestValues[feature],
testFn = testFunctions[feature];
if (!testVal) {
return false;
}
testDiv.style[jsPrefixedProperty] = testVal;
var computed = window.getComputedStyle(testDiv);
if (testFn) {
return testFn(jsPrefixedProperty, computed);
}
else {
return computed[jsPrefixedProperty] === testVal;
}
}
return false;
}
//Assume browser without getComputedStyle is either IE8 or something even more poor
if (!window.getComputedStyle) {
return false;
}
//Create a div for tests and remove it afterwards
if (!testDiv) {
testDiv = document.createElement('div');
document.body.appendChild(testDiv);
setTimeout(function () {
document.body.removeChild(testDiv);
testDiv = null;
}, 0);
}
var cssPrefixedProperty,
jsPrefixedProperty;
for (var i = 0; i < vendors.length; i++) {
if (i === 0) {
cssPrefixedProperty = feature; //todo: this code now works for single-word features only!
jsPrefixedProperty = feature; //therefore box-sizing -> boxSizing won't work here
}
else {
cssPrefixedProperty = '-' + vendors[i] + '-' + feature;
jsPrefixedProperty = jsPrefixes[i] + featureCapital;
}
if (isStyleSupported(feature, jsPrefixedProperty)) {
return {
vendor: vendors[i],
cssStyle: cssPrefixedProperty,
jsStyle: jsPrefixedProperty
};
}
}
return false;
}
Github: https://github.com/easy-one/CSS3test
Github:https: //github.com/easy-one/CSS3test
回答by f0rmat1k
if (window.TransitionEvent){
}
回答by Jbird
With Modernizr 3.0 (alpha), you can generate custom builds locally. This may resolve the aforementioned "overkill" concern - although i'm not entirely clear on that concern in the first place (but i'm assuming it's size). The new api provides a 'build' method, to which you can pass json containing the tests that you would like to include in the build.
使用 Modernizr 3.0 (alpha),您可以在本地生成自定义构建。这可能会解决前面提到的“矫枉过正”的问题——尽管我一开始并不完全清楚这个问题(但我假设它的大小)。新的 api 提供了一个“构建”方法,您可以向该方法传递包含您希望包含在构建中的测试的 json。
I use something like this in my gulp file but gulp is not needed - a simple node script will do.
我在我的 gulp 文件中使用了类似的东西,但不需要 gulp - 一个简单的节点脚本就可以了。
gulp.task('js:modernizr', function() {
var modConfig = JSON.parse(fs.readFileSync('modernizr-config.json', {
encoding: 'utf8'
}));
modernizr.build(modConfig, function(res) {
fs.writeFileSync('modernizr.js', res);
return true;
});
});
And an example of the 'modernizr-config.json' file would be
'modernizr-config.json' 文件的一个例子是
{
"classPrefix": "",
"options": [
"addTest",
"atRule",
"domPrefixes",
"hasEvent",
"html5shiv",
"html5printshiv",
"load",
"mq",
"prefixed",
"prefixes",
"prefixedCSS",
"setClasses",
"testAllProps",
"testProp",
"testStyles"
],
"feature-detects": [
"css/transforms",
"css/transforms3d",
"css/transformstylepreserve3d",
"css/transitions",
"touchevents",
"workers/webworkers",
"history"
]
}
The full config file is included in the Modernizr package.
完整的配置文件包含在 Modernizr 包中。
With this approach, you can take advantage of the well maintained Modernizr test suite via package installers and easily add/remove tests as needed. Less tests, smaller file obviously.
通过这种方法,您可以通过包安装程序利用维护良好的 Modernizr 测试套件,并根据需要轻松添加/删除测试。更少的测试,更小的文件显然。
The 'setClasses' option will add the related test class to your html but you can also take advantage of the 3.0 async events like so:
'setClasses' 选项会将相关的测试类添加到您的 html,但您也可以利用 3.0 异步事件,如下所示:
Modernizr.on('csstransitions', function(bool) {
if (bool === true) // do transition stuffs
}