Quick Tip: Detect CSS3 Support in Browsers with JavaScript
步骤 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会检测失败。所以我们要先检查参数的第一个字母是不是小写。如果是小写,就要转成大写。
这里我们使用了正则表达式来修正它。在上面这段代码中,我们检查了首字母是否是小写(^),如果是小写我们就用toUpperCase()将其转换为大写字母。
步骤 6
下一步我们来用vendors数组进行过滤,检测是否存在匹配的项;比如,如果我们传递box-shadow,我们需要检查div的style属性是否包含以下中的一个:
- MozBoxShadow
- WebkitBoxShadow
- MsBoxShadow
- OBoxShadow
- KhtmlBoxShadow
如果有匹配项,就返回true,因为浏览器本身提供了对box shadows的支持。
- 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支持),来测试一下吧!
步骤8: 用法
现在我们可以检测类名了,让我们一起测试一下。