高性能封装检测浏览器支持css3属性函数

css3出来已经好久了,如今来谈判断浏览器是否支持某个css3的属性虽然说有点过期了,可是仍是能够谈谈的,而后,此篇主要谈的不是判断是否支持,而是怎么封装更好,为何这么封装,欢迎吐槽。javascript

入题,判断浏览器是否支持css3 transition,方法很简单,只须要下面这句代码就好了:css

'transition' in document.body.style

chrome和ie支持document.body,可是Firefox不支持,Firefox支持document.documentElement,对于没有doctype声明的ie又不支持document.documentElement。html

因此用建立一个都支持的元素,而后经过判断属性在元素的style里是否存在便可:java

'transition' in document.createElement( 'i' ).style

固然这是标准下,对于老点的chrome或者Firefox,它们不支持transition,可是支持带前缀的transition,好比chrome 里css写成-webkit-transition: 1s;因而js也须要对这种状况进行断定,向后兼容。css3

如今贴一段简洁的封装代码,而后再逐步解析,以免繁杂,产生不了全局观:git

    function cssProperty( attr ){ var prefix = [ 'O', 'ms', 'Moz', 'Webkit' ], length = prefix.length, style = document.createElement( 'i' ).style; cssProperty =  function( attr ){ if( attr in style ){ return true; } attr = attr.replace( /^[a-z]/, function( val ){ return val.toUpperCase(); }); var len = length; while( len-- ){ if( prefix[ len ] + attr in style ){ return true; } } return false; }; return cssProperty( attr ); }

接下来是一段一段的解释。github

为何直接声明prefix = [ 'O', 'ms', 'Moz', 'Webkit' ]
而不使用字符串切割prefix = 'O ms Moz Webkit'.split( ' ' ),其余人不少都是这样写的。
经笔者测试,测试代码以下,为了避免必要的影响,我两段代码一块儿测试和两段代码分别测试都作了观察,结果无差。web

为了偷懒,估计其余浏览器应该也是差很少的结果就不作ie的测试了:chrome

测试结果以下,单位ms:数组

很明显,直接声明prefix = [ 'O', 'ms', 'Moz', 'Webkit' ]的代码执行效率更高。
再看[ 'O', 'ms', 'Moz', 'Webkit' ]是25个字节,'O ms Moz Webkit'.split( ' ' )是28个字节,即使是从文件大小方面,前者也优赛过后者。

然而为何不少国外包括jQuery源码里都是用split分割的形式呢?

(ps:jQuery-2.1.3源码5738行写cssPrefix时,是用的直接赋值,代码如右:cssPrefixes = [ "Webkit", "O", "Moz", "ms" ])

缘由我猜大概是这样的:对于分割的字符串种类比较多时,采用split有利于文件字节的减小,而执行效率缩小99999倍后几乎能够忽略不计,可是对于文件被下载更快,虽然说也能够忽略不计,可是选择这边比选择执行效率那边要好一点吧。

(ps:或许还有个缘由就是书写split的这条代码方便吧,不像数组那样,一会单引号,一会逗号方括号的...。若是是为了装逼就算了)

回归正题,回归到咱们这里,两边咱们都赛过,因此,毋庸置疑的就应该选择前者。

 

● 对于网上有些不缓存而每次去获取style的代码,我想说,难道同个浏览器环境下,下一秒这个元素的style就变了吗,难道不一样元素它是style也是变的,难道div元素支持transition,其余某个元素就不支持transition了?!还有就是不利于压缩,不利于文件尺寸的减少,提升下载速度。

下面这个代码来自国外的谁(固然中国好像不少都是直接不假思索的就拷贝过来了):http://code.tutsplus.com/tutorials/quick-tip-detect-css3-support-in-browsers-with-javascript--net-16444

 

● 仔细一看,会发现为何个人排列是这样的:O ms Moz Webkit,而别人的是这样的:Webkit Moz O ms;

理由来自2015年浏览器市场份额排行榜:http://tools.yesky.com/420/93749420.shtml

在国内,Opera PC版估计没什么用,并且它早已转向webkit内核了,ie就不谈了,对于开发者来讲坑太多了,看不到好效果就看不到吧,对不起了。

因此,整体来讲,排名依次是chrome,Firefox,ie,opera。

在后面的while循环判断代码中,是倒序判断的,因此从执行效率的角度讲,

大部分状况是chrome访问,因此就第一个判断webkit内核,知足条件就跳出循环,减小执行,提升运行效率。

 

● 个人代码里多了 var len = length; 用下面的代码测试一下,环境是(老版一点的)浏览器都只支持带前缀的这两个属性(好比Firefox13),测试国外代码第二个及之后的alert弹出的都会是false,由于它耗尽了len。

    alert( cssProperty( 'columns' ) ) alert( cssProperty( 'animation' ) )

 

● 函数封装以下封装,若是像国外那种柯里化封装表示js一加载完就会执行外层的匿名函数,而后把新函数赋值给supports,若是页面必定会用到检测函数,那么这种方法与下面的封装效果无差,可是若是页面不必定用到,即cssProperty变成了整站全局函数,或许另多个页面用到,因而像下面这样封装就不会形成函数的自执行,只有第一次调用函数的时候,函数才会执行,而后被赋予新值,详情能够参考一下《JavaScript高级程序设计第三版》惰性载入函数。

    function cssProperty( attr ){ //...code
 cssProperty =  function( attr ){ //...code
 }; return cssProperty( attr ); }

 

 最后欢迎访问个人Github,欢迎Star,欢迎Fork,一块儿成长。

 

相关文章
相关标签/搜索