本文原作链接:http://www.adobe.com/cn/devnet/dreamweaver/articles/using-modernizr.html
Modernizr 是一个用来检测浏览器功能支持情况的 JavaScript 库。 目前,通过检验浏览器对一系列测试的处理情况,Modernizr 可以检测18项 CSS3 功能以及40多项关于HTML5 的功能。 它比传统检测浏览器名称(浏览器嗅探)的方式更为可靠。 一整套测试的执行时间仅需几微秒。 此外,Modernizr 网站通过定制脚本只对你感兴趣的元素进行检测,从而实现效率优化。
官网: http://www.modernizr.com/ 。
文档:http://www.modernizr.com/docs/
检测对 CSS3 功能的支持
Modernizr 使用 JavaScript 检测浏览器所支持的功能,但是,它并不是使用 JavaScript 动态地加载不同的样式表,而是使用非常简单的技术将类添加到页面的<html>标签。然后作为设计者由你决定使用 CSS 层叠为目标元素提供合适的样式。例如,如果页面支持 box-shadow
属性,那么 Modernizr 会添加 boxshadow
类。如果不支持,那么它用 no-boxshadow
类作为替代进行添加。
只有不支持 box-shadow
的浏览器才会有 no-boxshadow
类,因此其它的浏览器不会应用这个样式规则。
表1列举了 Modernizr 使用的类名称以表明对 CSS3 的支持。 如果某个功能不支持,那么相应类的名称用no-
作前缀。
表1. Modernizr 检测的 CSS3 功能
CSS 功能 | Modernizr 类(属性) |
@font-face | fontface |
::before and ::after pseudo-elements | generatedcontent |
background-size | backgroundsize |
border-image | borderimage |
border-radius | borderradius |
box-shadow | boxshadow |
CSS animations | cssanimations |
CSS 2D transformations | csstransforms |
CSS 3D transformations | csstransforms3d |
CSS transitions | csstransitions |
flexible box layout | flexbox |
gradients | cssgradients |
hsla() | hsla |
multi-column layout | csscolumns |
multiple backgrounds | multiplebgs |
opacity | opacity |
reflection | cssreflections |
rgba() | rgba |
text-shadow | textshadow |
使用Modernizr检测HTML5的支持功能
Modernizr 为开始的<html>标签添加的类名称起着双重目的作用。当页面加载时,它们也是 Modernizr 对象创建的 JavaScript 属性的名称。表1列举了与 CSS 有关的类和属性的名称。表2列举了剩下的与 HTML5 和相关技术有关的类和属性,例如地理位置。
表2. Modernizr 检测的与 HTML5 有关的功能
HTML5 有关功能 | Modernizr 类(属性) |
Application cache | applicationcache |
Audio | audio.type (ogg, mp3, wav, m4a) |
Canvas | canvas |
Canvas text | canvastext |
Drag and drop | draganddrop |
Form input attributes | input.attributeName |
Form input elements | inputtypes.elementName |
Geolocation | geolocation |
hashchange event | hashchange |
History management | history |
IndexedDB | indexeddb |
Inline SVG | inlinesvg |
Local storage | localstorage |
Messaging | postmessage |
Session storage | sessionstorage |
SMIL | smil |
SVG | svg |
SVG clip paths | svgclippaths |
Touch events | touch |
Video | video.type (ogg, webm, h264) |
WebGL | webgl |
Web sockets | websockets |
Web SQL database | websqldatabase |
Web workers | webworkers |
在大多数情况下,表1和表2列举的所有属性返回的都是 true
或者 false
。所以,你可以按照如下所示使用 JavaScript 对本地存储进行测试:
if (Modernizr.localstorage) {
// script to run if local storage is supported
} else {
// script to run if local storage is not supported}
然而,就 audio
和 video
而言,返回值是一个字符串,它表明着浏览器能够处理特定类型的置信水平。 根据 HTML5 规范,空的字符串表示该类型不支持。 如果支持该类型,那么返回值是“maybe”或是“probably”。 例如:
if (Modernizr.video.h264 == "") {
// h264 is not supported
}
使用 Moder 年 izr 加载外部脚本
当创建Modernizr的自定义production版本时,在默认情形下,必须选中包含 Modernizr.load()
的选项。Modernizr.load()
是 yepnope()
的别名,它是与 Modernizr 同步开发的独立脚本加载器。 为了说明如何使用它,我给出一个简单范例。我已经将相应的脚本从 required.html 移到了 check_required.js,并且做了三个微小的改动以便于去除 Modernizr 测试以及将它赋值到一个名为 init
的变量中。 修订的脚本如下所示:
var init = function() {
// get the form and its input elements
var form = document.forms[0],
inputs = form.elements;
// put the focus in the first input field
inputs[0].focus();
// check required fields when the form is submitted
form.onsubmit = function() {
var required = [], att, val;
// loop through input elements looking for required
for (var i = 0; i < inputs.length; i++) {
att = inputs[i].getAttribute('required');
// if required, get the value and trim whitespace
if (att != null) {
val = inputs[i].value;
// if the value is empty, add to required array
if (val.replace(/^\s+|\s+$/g, '') == '') {
required.push(inputs[i].name);
}
}
}
// show alert if required array contains any elements
if (required.length > 0) {
alert('The following fields are required: ' + required.join(', '));
// prevent the form from being submitted
return false;
}
};
};
Modernizr.load()
的一个很大的优点是,根据测试浏览器能力的结果,它可以有条件地加载脚本—这就是为什么起初叫它 yepnope()
的原因。 它可以异步地加载外部脚本—换句话说,就是能够在浏览器已加载 Document Object Model (DOM) 之后加载外部脚本—因此它可以有助于提升你的网站性能。
Modernizr.load()
的基本语法是将一个具有如下属性的对象传递给它:
-
test
: 你希望检测的 Modernizr 属性。 -
yep
: 如果测试成功,你希望加载的脚本的位置。 使用一个多脚本数组。 -
nope
: 如果测试失败,你希望加载的脚本的位置。 使用一个多脚本数组。 -
complete
: 外部脚本一经加载就运行的函数(可选)。
yep
和 nope
两者都是可选的,只要你提供了其中一个即可。
为了在 check_required.js 中加载和执行脚本,需要在 modernizr.adc.js 已附着到页面之后添加如下<script>
块(代码位于required_load.html 中):
<script>
Modernizr.load({
test: Modernizr.input.required,
nope: 'js/check_required.js',
complete: function() {
init();
}});
</script>
这样就与之前运行的完全一致,但是却可以降低已支持 required
属性的浏览器的下载负荷。
为了测试多种条件,你可以给 Modernizr.load()
传递一组对象。如需获得更多细节信息,参见 Modernizr 文档上的Modernizr.load() 教程。
Modernizr 是一个强大而有用的工具,但是这并不意味着你就应该使用它。 并不是在所有情形下均必须使用 Modernizr 给浏览器提供多种样式。 如果你主要关注的对象是 Internet Explorer,那么考虑使用IE conditional comments。 你也可以使用CSS层叠覆盖一些样式。 例如,先使用hexadecimal color,然后使用rgba()
或 hsla()
覆盖它。 旧版本的浏览器会使用第一个值并且忽略第二个值。
Modernizr 真正地变成现实是当它与 polyfills 和其它 JavaScript 相结合的时候。但是记住,通常很容易创建属于你自己的适合支持功能的测试。例如,下面就是你测试某个浏览器是否支持 required
属性的全部代码(代码位于required_nomodernizr.html 中):
var elem = document.createElement('input');
if (typeof elem.required != 'boolean')
{
// required is not supported
}