您的位置:首页 > Web前端 > JavaScript

使用javascript判断浏览器对css3的支持情况【译】

2013-09-09 18:59 751 查看

Quick Tip: Detect CSS3 Support in Browsers with JavaScript

Jeffrey Way on Nov 15th 2010

步骤 1

首先我们要确定我们想如何调用 函数。在这里我们会简化我们的方法调用如下:

if ( supports('textShadow') ) {
document.documentElement.className += ' textShadow';
}


这应是最终的函数调用方式,即当我们给supports()函数传递一个CSS属性名称的时候,它会返回一个boolean。如果为true,则将classname附加到documentElement 或<html>上。这样我们就有了一个新的可用类名。

步骤 2

下一步,构建supports()函数。

var supports = (function() {

})();


我们为什么不把supports函数构建成标准函数的样子呢?——因为我们需要先做一些准备工作,而我们显然不应当每次调用函数的时候,都去重复这些准备工作。因此,最好使supports函数等于它自己执行的函数所返回的内容(it’s best to make
supports
equal to whatever is returned from the self-executing function)。

步骤 3

为了测试浏览器是否支持特定的属性,我们需要创建一个“哑巴”元素,这个动态创建的哑巴元素实际上不会插入到DOM中。

var div = document.createElement('div');


相信你已经注意到,当使用CSS3新属性时,我们有很多可以使用的代理前缀:

-moz

-webkit

-o

-ms

-khtml

我们的函数需要过滤并检测这些前缀,所以让我们把这些前缀放到一个数组里,数组名为vendors:

var div = document.createElement('div'),
vendors = 'Khtml Ms O Moz Webkit'.split(' ');



的确,使用split()函数从字符串中创建数组比较懒,但是确实很节省时间~~嘿嘿


我们即将通过这个数组来进行过滤,同时也存储一下这个数组的长度。

var div = document.createElement('div'),
vendors = 'Khtml Ms O Moz Webkit'.split(' '),
len = vendors.length;


以上就是supports()的准备工作,因为它是静态的,所以不需要每次调用supports()的时候都执行一次。这也是为什么当页面加载时,我们只执行一次。 现在让我们return实际赋值给supports变量的函数吧。

return function(prop) {

};



闭包的魅力在于,即使supports()函数与返回的函数一样,它还是可以使用div,vendors和len变量。



步骤 4

快速检测:如果传递的属性是有效的div style属性,那么浏览器支持这个属性,返回true:

return function(prop) {
if ( prop in div.style ) return true;
};


比如CSS3属性 text-shadow,大多数的现代浏览器都默认支持它,不需要给它添加代理前缀。所以我们没有必要给所有的属性都添加一个代理前缀,也因此我们无需在一开始就检测代理前缀。

步骤 5

你可能喜欢这样写CSS3的属性名称,如
-moz-box-shadow,然而如果在Firebug中查看类型对象(style object),你会发现它拼作MozBoxShadow。因此,如果我们这样检测:


'mozboxShadow' in div.style // false


它会返回false,这个值是大小写敏感的。




这就意味着,如果用户给supprots()函数传参boxShadow会检测失败。所以我们要先检查参数的第一个字母是不是小写。如果是小写,就要转成大写。

return function(prop) {
if ( prop in div.style ) return true;

prop = prop.replace(/^[a-z]/, function(val) {
return val.toUpperCase();
});

};


这里我们使用了正则表达式来修正它。在上面这段代码中,我们检查了首字母是否是小写(^),如果是小写我们就用toUpperCase()将其转换为大写字母。

步骤 6

下一步我们来用vendors数组进行过滤,检测是否存在匹配的项;比如,如果我们传递box-shadow,我们需要检查div的style属性是否包含以下中的一个:

MozBoxShadow

WebkitBoxShadow

MsBoxShadow

OBoxShadow

KhtmlBoxShadow

如果有匹配项,就返回true,因为浏览器本身提供了对box shadows的支持。

return function(prop) {
if ( prop in div.style ) return true;

prop = prop.replace(/^[a-z]/, function(val) {
return val.toUpperCase();
});

while(len--) {
if ( vendors[len] + prop in div.style ) {
return true;
}
}
};


尽管我们可以对数组进行for循环来过滤匹配项,但是在这个问题中上我们没必要这么做,因为:

array元素的顺序并不重要

while语句写起来更快速并且写的字符也更少

有一点点的性能提高

不要被vendors[len] + prop这个语句所迷惑,只要把那些名称替换为真实的值就可以了:MozBoxShadow

步骤 7

但是,如果以上的值全都不匹配呢?这种情况下,浏览器很有可能不支持这个属性,那么就应该返回false。

while(len--) {
if ( vendors[len] + prop in div.style ) {
return true;
}
}
return false;


That should do it for our function! Let’s test it out, by applying a
className
to the
html
element, if the browser supports, say, the
text-stroke
property (which only webkit does).

好啦,现在我们来测试一下我们的函数吧! 通过给html元素添加一个类名称(className),如text-stroke(仅webkit支持),来测试一下吧!

if ( supports('textStroke') ) {
document.documentElement.className += ' textStroke';
}


步骤8: 用法

现在我们可以检测类名了,让我们一起测试一下。

/* fallback */
h1 {
color: black;
}

/* text-stroke支持 */
.textStroke h1 {
color: white;
-webkit-text-stroke: 2px black;
}


最终源代码

var supports = (function() {
var div = document.createElement('div'),
vendors = 'Khtml Ms O Moz Webkit'.split(' '),
len = vendors.length;

return function(prop) {
if ( prop in div.style ) return true;

prop = prop.replace(/^[a-z]/, function(val) {
return val.toUpperCase();
});

while(len--) {
if ( vendors[len] + prop in div.style ) {
// 浏览器支持box-shadow,做你需要的操作吧!
// 或如果浏览器不支持,就用使用叹号(!)检测 Or use a bang (!) to test if the browser doesn't.
return true;
}
}
return false;
};
})();

if ( supports('textShadow') ) { document.documentElement.className += ' textShadow'; }


如若获取更广泛的解决方案,请参考Modernizr library.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: