渐进增强 HTML5 表单

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费积分!

我认为这是目前渐进增强表单的最佳方法。也就是说,在可用时使用 HTML5 功能,在不可用时回退到 JavaScript 替代方案。

加载 Yepnope.js

<script src="scripts/yepnope.js"></script>

Yepnope 是一个“脚本加载器”,它会有条件地加载脚本。您向它提供某种布尔值(true 或 false),如果为 true,它将加载一组脚本(或 css),如果为 false,则加载另一组。我们从哪里获得该布尔值?通过使用…测试功能。

加载 Modernizr

<script src="scripts/modernizr.js"></script>

Modernizr 使您能够测试 HTML5 和 CSS31 功能。例如,在加载 Modernizr 后,Modernizr.inputtypes.date 如果您在支持类型为日期属性的输入的浏览器中(大约从版本 9 开始只有 Opera),则为 true,如果在不支持日期类型的浏览器中,则为 false。

更好的是:您可以获取仅包含所需测试(输入类型和输入属性)的 Modernizr 自定义版本,以及在 Modernizr 2 测试版构建器 中内置的 Yepnope。

结合两者

这两个很棒的工具都已准备就绪,我们可以结合它们的功能。

yepnope({
  test : Modernizr.inputtypes.date,
  nope : [
      // load scripts to simulate date type
  ]
});

在这种情况下,我们不需要“yep”,因为“yep”表示浏览器支持它,因此我们不需要任何帮助。

我们需要什么作为回退?

由于我们一直在使用 HTML5 输入类型日期作为示例,因此让我们考虑一下它的回退。jQuery UI 有一个 非常棒的日期选择器。jQuery 可能有助于我们解决许多回退问题,因此这将是一个不错的选择。要使日期回退正常工作,我们需要加载四个资源

  1. jQuery
  2. jQuery UI
  3. jQuery UI 的 CSS
  4. 我们自己的调用日期选择器的脚本

加载它们

使用我们的 Yepnope/Modernizr 组合,该清单如下所示

yepnope({
  test : Modernizr.inputtypes && Modernizr.inputtypes.date,
  nope : [
	'scripts/jquery.js', 
	'scripts/jquery-ui.js',
	'css/jquery-ui.css',
	'scripts/datepicker.js'
  ]
});

我们的自定义脚本(由 Yepnope 加载最后)可能就像尽快调用日期选择器函数一样简单

// DOM ready function because we should probably
// be doing this in the <head>
$(function() {
	$("input[type='date']").datepicker();
});

现在我们得到

Opera 11

原生支持,没有加载额外的脚本

Firefox 4

没有原生支持,使用 jQuery UI 日期选择器。

继续

日期类型支持不是我们唯一可以在这里做的事情。假设我们也希望使用占位符。摇滚乐,只需使用另一个 yepnope 测试即可

yepnope({
  test : Modernizr.input.placeholder,
  nope : [
	'scripts/jquery.js', 
	'scripts/placeholder.js'
  ]
});

请注意,我们再次使用 jQuery,因此指定了 jQuery 库脚本。假设我们在一个不支持日期或占位符的浏览器中,并且我们计划对这两种回退都使用 jQuery。为了以最佳方式执行此操作,我们将需要 jQuery 的测试组合到它自己的 yepnope 块中,这样我们就不会多次加载 jQuery。

yepnope([
  {
    test:  Modernizr.input.placeholder || (Modernizr.inputtypes && Modernizr.inputtypes.date),
    nope: 'jquery.js'
  },
  {
    test : Modernizr.inputtypes && Modernizr.inputtypes.date,
    nope : [
	'scripts/jquery-ui.js',
	'css/jquery-ui.css',
	'scripts/datepicker.js'
  ]},
  {
    test : Modernizr.input.placeholder,
    nope : 'scripts/placeholder.js'
  }
]);

比 Polyfills 更酷

Polyfills 与此精神相同。它们测试功能支持,如果可能,使用原生技术,否则以某种方式伪造它。它们很棒。这与 polyfills 不同,因为我们不需要进行测试,我们已经使用 Modernizr 做到了。因此,我们加载的脚本可以假设没有支持并从此开始。我认为这可能比 polyfilling 更好,因为

  1. 我们最初只加载两个脚本。如果浏览器非常现代,那么它将永远加载的只有这些。使用 polyfill 脚本,您需要为每个功能加载一个脚本。
  2. 我们将功能检测外包给 Modernizr,这是一个完全致力于以最佳方式执行此操作的项目。在这方面,polyfill 脚本可能维护得不够好。

或者…

我还没有过多地使用它们,但是有一些项目旨在为 HTML5 表单的每个功能提供 polyfill。其中一个是 webforms2。我有点喜欢自己进行功能测试和回退的控制,但是对一劳永逸的方法肯定有吸引力。

 


1 Modernizr 测试其他一些花哨的 Web 功能,这些功能在技术上不是 HTML5 或 CSS3,但通常与它们分组,例如 @font-face。