HTML5 和 CSS3 的快速发展,给我们带来了极大的便利,比如从此再也不用花费大量的时间只是为了设计一个圆角的效果。
但是!我们不能像控制机器一样来控制所有的人都一夜之间升级到现代浏览器,因为那些 不够现代的浏览器 诞生之时,HTML5和CSS3尚未被正式推出。
于是,我们的问题来了:针对那些不支持新特性的浏览器而言,我们是直接放弃这些用户群呢,还是直接不用这些新特性,老老实实的用图片拼出圆角的特效?
我想,答案是显而易见的。我们不能放弃那些因为这样那样的原因没法升级他们的浏览器用户,但也不能委屈了自己,不能用这些很酷的技术来写代码。
在jQuery 1.9发布之前,jQuery内置了一个 jQuery.browser 函数来检测浏览器的版本,它根据user agent来返回浏览器的相关信息。我们可以根据结果得到用户浏览器版本,这样就像打一些补丁一样针对这些老的浏览器做一些fallback的工作。
可是jQuery 1.9发布的时候取消了这一API(当然你可以使用 jQuery.migrate 插件),官方文档中解释为我们应该用检测feature的方案( jQuery.support )来判断我们需不需要fallback,毕竟user agent伪造太容易了。比如 Chrome Mobile 版本则会加入Safari的user agent,这也是为什么移动浏览器市场Safari雄踞第一的真正原因之一。
本文向你介绍 Modernizr.js 这个类库,可以说它干的事情目的与jQuery.support并无二致,但是功能和成熟程度在整个领域都是首屈一指的。
Modernizr帮助我们检测浏览器是否实现了某个feature,如果实现了那么开发人员就可以充分利用这个feature做一些工作,反之没有实现开发人员也好提供一个fallback。所以,我们要明白的是Modernizr只是帮我们检测feature是否被支持,它并不能够给浏览器添加那些本来不支持的feature。
Modernizr在2010和2011年均赢得了 .net Award for Open Source App of the Year ,要知道它的竞争对手都是像Wordpress、Drupal这些重量级选手。同时在2011年,它的首席开发者 Paul Irish 赢得了Developer of the Year大奖。
其实,这个类库使用非常简单,简单到你把 官方文档 (单页)从头到尾看一遍就完全了解它的使用方法了。接下来,我做一点简单的介绍。
在官方网站( http://modernizr.com )上我们可以看到有两个下载选项,Development和Production版本。其实它们都会导向同一个下载页面,只不过前者会帮我们把选项预先勾上而已。
通常我们需要检测的新特性基本都囊括在了这些选项中,我们可以根据自己需要,定制化的选择需要检测的feature。
下载完后我们就可以在 <head>
中引用这个类库。由于Modernizr帮我们内置了html5shiv 类库,所以我们必须在 <body>
加载之前引用这个类库。当然你如果针对的是IE9+的浏览器,那么大可以在页面元素加载完后再引入,但这样就会有 FOUC 这样极不友好的效果出现。
最后,我们需要在 <html>
标签中加入 no-js
类,以免浏览器禁用了JavaScript。
使用了Modernizr后,页面中渲染后的html代码是这个样子的:
其中有很多以no作为前缀的class,当然大部分都没有这个前缀。事实上,如果一个类名以no作为前缀,比如 no-touch
这表示浏览器不支持touch特性,这也是最新版本的Chrome不支持的两个feature之一:
Modernizr有一个 test页面 ,可以检测当前浏览器支持的特性。Chrome目前是对HTML5和CSS3新特性支持最好的浏览器,没有之一。
言归正传。当我们引入了Modernizr.js类库后, <html>
标签的class属性就会被相应的赋值,以显示浏览器是否支持某类CSS属性。比如在IE6下面,不支持boderradius特性,那么在 <html>
标签中就会出现 no-borderradius
类,我们可以做一些fallback的工作:
.no-borradius div{ /*-- do some hacks here --*/}
检测浏览器是否支持某项特性,我们可以用这种语法:
if(Modernizr.webgl){ /* support WebGL */} else{ /* not support WebGL */}
基于 YepNope.js ,Modernizr.load()根据一些条件判断来动态选择加载CSS和JavaScript,这无疑对避免不必要的资源加载有极大的帮助。
你可以在这里( HTML5 Cross Browser Polyfills )找到几乎所有新特性的fallback解决方案。
Modernizr.load( test: Modernizr.webgl, yep : 'three.js', nope: 'jebgl.js' );
当浏览器支持WebGL的时候,就引入 three.js 这个类库做一些3D效果。浏览器不支持WebGL的时候可以使用 jebgl.js 做一些fallback操作。
还有一个比较酷的例子来自官方文档。我们在用jQuery类库的时候,通常都是这种写法:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js"> </script><script>window.jQuery || document.write('<script src="js/libs/jquery-1.7.1.min.js">\x3C/script>')</script>
现在用Modernizr.load()可以这么写:
Modernizr.load([ { load: '//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js', complete: function () { if ( !window.jQuery ) { Modernizr.load('js/libs/jquery-1.7.1.min.js'); } } }, { // This will wait for the fallback to load and // execute if it needs to. load: 'needs-jQuery.js' } ]);
Modernizr为我们做了最复杂的一步,我们只需要像模块一样将代码组装起来。当然,Modernizr还有一些其他的用法,比如Modernizr.mq()方法用来检测media query,这对Responsive Design可以帮上很多忙。诸如这些API在官方文档中都有涉及,建议在使用的时候仔细了解一下即可。
Modernizr无疑是成功的,在主页下方,它明确的标识它的著名用户:
当我们在Visual Studio中创建Web应用程序的时候,默认模板中便引入了Modernizr.js类库。
自从有了Modernizr.js,开发人员可以开心的编码了,哪怕我们嘴上还是会喋喋不休的诅咒那些“不够友好”的浏览器。
但是,谁又真正在乎呢。
这个js在国外经常看到有用,不过前端开发博客博主不推荐用:点我
列举了一些理由,包括代码量和维护等等方面。