我认为这是目前渐进增强表单的最佳方法。也就是说,在可用时使用 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 可能有助于我们解决许多回退问题,因此这将是一个不错的选择。要使日期回退正常工作,我们需要加载四个资源
- jQuery
- jQuery UI
- jQuery UI 的 CSS
- 我们自己的调用日期选择器的脚本
加载它们
使用我们的 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 更好,因为
- 我们最初只加载两个脚本。如果浏览器非常现代,那么它将永远加载的只有这些。使用 polyfill 脚本,您需要为每个功能加载一个脚本。
- 我们将功能检测外包给 Modernizr,这是一个完全致力于以最佳方式执行此操作的项目。在这方面,polyfill 脚本可能维护得不够好。
或者…
我还没有过多地使用它们,但是有一些项目旨在为 HTML5 表单的每个功能提供 polyfill。其中一个是 webforms2。我有点喜欢自己进行功能测试和回退的控制,但是对一劳永逸的方法肯定有吸引力。
1 Modernizr 测试其他一些花哨的 Web 功能,这些功能在技术上不是 HTML5 或 CSS3,但通常与它们分组,例如 @font-face。
实际上,您不需要 Yepnope + Modernizr,您可以直接使用 Modernizr,其中包含来自此处的 Yepnope http://modernizr.github.com/Modernizr/2.0-beta/ 检查其他部分(Modernizr.load)
该死,你抢先一步了,哈哈
您好,这非常有帮助,谢谢。由于已经过去了 3 年,并且事情发展迅速,想知道您是否对这篇文章进行了更新。
来到这个网站是为了查找一些表单样式内容,而这是您最近的帖子——Chris,您真是个读心术大师!
嘿,您可以自定义您的 Modernizr 下载以随附 yepnope http://modernizr.github.com/Modernizr/2.0-beta/ 您知道吧 :)
如果我的这条评论收到 10 条回复,我将向日本的慈善项目捐款 150 美元。 :)
1
2
上帝保佑你 :)
3
4 – 干得好!
5 – 做吧!:D
这是对您评论的回复,以便您可以向日本的慈善项目捐款。感谢您的善意。
我认为无论评论回复如何,您都应该这样做。
9
还有10。现在我觉得我帮了一点小忙: )
糟糕:D 我忘记在这个数字后面加一个零了。我想说的是1500美元:D
@Chris: 好吧,现在有超过10个人参与其中,这让我和他们对这件事感觉更好 :)
你想再加点吗?
为了日本,我将说你好。长期读者,从未发帖。喜欢CSS-Tricks,希望你在那个Adel上一切顺利。
干杯。
我今天正在编写一个日期选择器(我将在完成时发布它;),我也面临着同样的困境。Opera有一个非常不错的原生日期选择器,尽管有点丑。但是,Webkit只是显示了一个很糟糕的类似旋转器的控件,这绝对不友好。但是,没有办法安全地检测浏览器实现的日期选择器是不错的还是仅仅是他们用来表示“我们也实现了日期控件”的一种方式,而实际上并没有为作者提供价值。
因此,在我的情况下,我选择使用JavaScript版本,并在JS不可用时回退到任何原生控件。我不高兴我不得不这样做,但是由于@#*&^% Webkit,我认为这是唯一的方法。:(
请发布它!日期选择器一直对我怀有强烈的仇恨,在这一点上,这种感觉是相互的。
干杯。
真正令人恼火的是,Webkit浏览器报告支持日期/时间输入类型,但它们的实现完全失败了。正如Lea指出的那样,控件本身非常糟糕,但更糟糕的是,用户必须以正确的(机器可读)格式输入值,否则浏览器将拒绝提交表单,并且根本不提供任何反馈!
我不愿说,但这有点回到了浏览器嗅探——除了Opera之外的任何东西都需要JS日期选择器。
Modernizr 报告当前的 webkit <input type=date> 为不支持。我从背后的 Webkit 工程师那里得到了确认,在 UI 就位之前,他不会添加输入验证(这会导致 Modernizr 通过)。
http://formalize.me/
?
…处理表单的外观,而不是功能。(不过它超级棒,在外观方面)
嗯,此页面上此网站的右侧面板被弄乱到底部了
– 关于主题:) 我同意Gabri的观点
你好,
非常好,但是应该在字段中阻止选定的值。这样,我们将保护正确的值。
如果每一篇文章都能提到哪些浏览器确切支持这种(或其他)类型的自定义,那就太好了。
但无论如何,这是一篇好文章。谢谢。
这很有趣,但我有两个问题
1)假设我正在使用像Typo3这样的CMS,并且我添加了一个包含jQuery的扩展(不确定的版本,可能是旧的,也可能是新的)。
当yepnode第一次尝试加载jQuery库时,它会检测到已经加载了一个库,还是会再次加载它?
2)是否可以使用此方法来实现聪明的HTML5boilerplate?
[[来自http://html5boilerplate.com/ 中index.html的第54-56行]]
如果您无论如何都在加载jQuery,则无需使用yepnope加载它作为回退,只需将其从“nope”中要加载的文件数组中删除即可。我认为yepnope不会检测到它自己没有加载的脚本。
Chris Coyier就是Andy McKee,就是Chris Coyier
http://onemansblog.com/wp-content/uploads/2008/12/andy-mckee.jpg
哈哈。我也想过同样的事情。我想知道哪个名字是别名,哪个名字是真名。
从未听说过yepnope。开始使用modernizr进行css片段,但这种组合非常流畅。
不太明白这些代码的真正含义,但我开始理解了一些……感谢您的提示。
为了初始化日期选择器,我建议这样做
这可以防止脚本加载过程中可能发生的任何异常/延迟。由于您的脚本加载是延迟的,因此在加载
datepicker.js
之前完全有可能触发jQueries doc ready。这通过在与datepicker.js
加载相关的回调中注册doc ready函数来防止这种情况。此外,我们收到了多个关于不加载相同脚本两次的请求。这确实是一个有效的用例,我们可能会在将来的版本中使用它。
感谢这篇文章。
非常聪明的技巧,Chris。谢谢。
每个网页开发者都应该了解渐进增强和Ari技术,仍然有一些开发者使用旧式的标记,我建议他们应该阅读这篇文章
既然您提到了一个占位符回退脚本/polyfill,但实际上没有链接到示例,请允许我推广我的jQuery占位符插件 :)
理论上,如果人们使用它,他们可以(也许应该)删除顶部的if/else isSupported内容,因为这是首先进行Modernizr测试的意义所在,此脚本不需要进行自己的测试。
但是,我不认为Modernizr对textarea和input进行单独的测试,而且我知道您知道那里存在一些浏览器差异(Opera 11和Safari 4在input上支持它,但在textarea上不支持)。
关于这些东西有很多需要注意的地方。
在某些浏览器中,本文中的代码将无法工作。这是因为Modernizr仅报告存在的项目,所有其他项目都是未定义的。因此,在不支持任何HTML5输入类型的浏览器中,您会收到错误
要解决此问题,请添加一个保护条件
我一直在尝试找出如何定义inputtypes,但没有看到任何理由。如果您有更多详细信息或测试用例,我很乐意获得它。
工作量太大。我宁愿只使用最低公分母,而不是做额外的工作并增加维护。
我刚刚构建了日期选择器回退,但遇到了一个讨厌的问题!
支持HTML5的Opera将日期格式化为yyyy-mm-dd,而我需要此格式为dd/mm/yyyy。
是否可以使用HTML5调整格式,或者我应该在此基础上构建一个JS修复程序?
YYYY-MM-DD 是 ISO 8601 格式。你需要自己将其转换为 DD/MM/YYYY。如果可能,我建议在服务器端进行转换,但在发送数据之前客户端进行转换也可以。
很棒!!!HTML5 即将大放异彩!!
仅仅在 type=date 上实现一个日期选择器是行不通的,因为
1. HTML5 日期选择器的格式始终为 yyyy-mm-dd
2. type=date 具有多个功能,例如 min/max、step、valueAsNumber、valueAsDate,这些功能需要用于配置日期选择器 polyfill,并且您必须尊重对这些属性的动态更改。
@Jeroen
您必须“修复”此问题。最简单的方法是始终使日期选择器使用 yyyy-mm-dd。
如果您需要其他(本地化的)格式,则需要使用 JavaScript 来实现。但您不能将其添加到 date 类型中,此类型始终发送 yyyy-mm-dd。如果您不这样做:较新的 WebKit(Chrome 10+)将无法提交您的表单。您必须隐藏 input[type=date],创建一个新的 input[type=text],将日期选择器添加到此新输入中,然后使用正确的格式同步这两个输入元素。
实际上,我已经编写了一个 polyfill,它显示本地化的视图(默认值为用户代理的语言环境,但可以配置)并始终向服务器发送正确指定的 HTML5 数据。您可以在 @http://afarkas.github.com/webshim/demos/index.html 找到它。
也就是说,如果您想要类似于 HTML5 所做的事情,这里的教程是可以的,但如果您需要实现正确代码的东西,则应该使用类似于 webshims 库 的东西。根据我的测试,webshims 库目前拥有唯一有效的表单 polyfill,它可以正确地实现新的 Web 表单内容(-> 准确,符合规范)
此致
alex
(披露:我是 webshims 库的创建者……)
感谢您提供这篇内容丰富的文章。我一直在使用 Modernizr,但之前从未遇到过 yepnope.js。
另外,我在另一个网站上偶然发现了本文的逐字复制,并想提醒您注意此事,以防它是未经授权的复制。
有问题的网站是
www_phphosts_org/2011/03/progressively-enhancing-html5%C2%A0forms/(将下划线替换为点 - 我不想链接到它们)。
自从我开始我的网页设计之旅以来,表单一直是我的痛点,但有了您的酷炫教学和 HTML5,我爱上了它!谢谢 Chris!您才是真正的 McCoyier! :)
我最近一直在为我的 PHP 做很多关于 HTML 表单的工作。看看我如何将这种新技术集成到我的表单中会很有趣。