--- title: 旧式浏览器中的HTML 表单 slug: Learn/Forms/HTML_forms_in_legacy_browsers translation_of: Learn/Forms/HTML_forms_in_legacy_browsers original_slug: Learn/HTML/Forms/HTML_forms_in_legacy_browsers ---
所有 web 开发者很快就会(有时候是痛苦地)发现网络是一个令人不快的地方。我们碰到的最恶毒的诅咒是旧式浏览器。好吧,让我们承认吧,当我们提到 “旧式浏览器” 时,脑海中出现就是 老版本的 Internet Explorer ……但是,这远远不是全部。只发布一年的 Firefox 比如 the ESR version 也是旧式浏览器。那么,在移动世界呢?当浏览器和 OS(操作系统) 都不能更新时?是的,有非常多老版本的 Android 手机或 iPhone 没有更新到最新的浏览器。它们同样是旧式浏览器。
可悲的是,处理这些传统浏览器的问题是工作的一部分。幸运的是,有一些技巧可以帮助您解决旧式浏览器导致的大约80%的问题。
实际上,最重要的事情是阅读那些浏览器的文档,并尝试理解通用的(解决)模式。例如,在许多情况下,HTML表单是否支持CSS是最大的问题。这是正确的开始,只需要检查你想用的元素或接口是否支持CSS即可。MDN有一个关于包含HTML中可用的元素、属性或API的兼容表单可查。 此外,仍有其他一些非常有用的资源:
由于HTML forms 包含复杂的交互,所以有一条法则: keep it as simple as possible。很多时候,我们想让表单更美观或想使用更高级的技术,然而,构建高效的HTML表单不只是设计和技术问题。记得花时间读一下这篇文章t forms usability on UX For The Masses.
Graceful degradation and progressive enhancement 是一个开发模式,它允许你通过同时支持多种浏览器来构建优秀内容。当你为现代浏览器构建内容时,你想确保它能在旧式浏览器中以某种方式工作,这就是优雅地降级(graceful degradation).
让我们看一些关于HTML表单的例子:
HTML5引入的新input类型十分酷,因为他们的降级(degrade)是高度可预测的。如果一个浏览器不能理解 {{HTMLElement("input")}}元素的 {{htmlattrxref("type","input")}} 属性, 它将会后退到text
一样的行为。
<label for="myColor"> Pick a color <input type="color" id="myColor" name="color"> </label>
Chrome 24 | Firefox 18 |
---|---|
![]() |
![]() |
CSS属性选择器 在 HTML Forms 中十分有用,然而旧式浏览器不支持. 在那种情形下,一般会习惯性使用等价的class:
<input type="number" class="number">
input[type=number] { /* 这在一些浏览器中是不能执行的 */ } input.number { /* 可以在任何浏览器中执行 */ }
注意下面的写法没有用(由于它是重复的),在某些浏览器中会失败:
input[type=number], input.number { /* 在某些浏览器中,这可能会失败,因为如果他们不理解其中任何一个选择器,则跳过整个规则 */ }
有两种定义HTML表单按钮的方式:
button
, submit
, reset
or image
如果你想通过元素选择器在按钮上应用CSS的话,采用 {{HTMLElement("input")}} 元素的方式会让事情变得稍微有点复杂:
<input type="button" class="button" value="click me">
input { /* 此规则关闭了input元素定义的按钮的默认渲染样式 */ border: 1px solid #CCC; } input.button { /* 这条规则不会恢复默认渲染*/ border: none; } input.button { /* 这条也不会(恢复)! 实际上在浏览器中没有标准方式实现这一目标 */ border: auto; }
{{HTMLElement("button")}} 元素有两个问题令人困扰:
submit
作为 {{htmlattrxref("type","button")}} 属性的默认值, 所以建议总是在{{HTMLElement("button")}} 元素上设置设置 {{htmlattrxref("type","button")}} 属性.<!-- 某些情形下,点击按钮将发送 "<em>Do A</em>" 而不是值"A" --> <button type="submit" name="IWantTo" value="A"> <em>Do A</em> </button>
给予你的工程限制来选择上述任一种解决方案。
HTML表单和旧式浏览器最大的问题是CSS的兼容性。正如你可以从这篇文章 Property compatibility table for form widgets 中看到的复杂性, 它非常的困难。即使仍然可以对文本元素(如大小、字体颜色等)进行一些调整,但那样做会有副作用。最好的办法还是不要美化HTML表单小组件。但你仍然可以将样式应用到表单周围的项目上。如果你是一个专业人士,并且你的客户需要那么做,在这种情况下,你可以研究一些硬技能,如 rebuilding widgets with JavaScript。但在那种情况下,最好还是毫不犹豫的让客户收回这些愚蠢的决定。
尽管JavaScript在现代浏览中是非常棒的技术,但在旧式浏览器中可能存在很多的问题。
API的兼容性是最大的问题。由于这个原因,与"不引人注意的(unobtrusive)" JavaScript一起工作被认为是最佳实践(译者注:此处意思是说没有/忽略JS或JS出了问题也能工作)。这个开发模式定义了两个需求:
The principles of unobtrusive JavaScript (最早是由Peter-Paul Koch为 Dev.Opera.com 所撰写,现在已转移到 Docs.WebPlatform.org) 同样阐述了上述观点。
有很多情形,好的"polyfill"能通过提供缺少的API以提供帮助。一个 polyfill 是一些JavaScript(脚本) 用于填补旧式浏览器中的功能缺失。虽然它们可以用来改进对任何功能的支持,并且使用它们Nederland风险小于CSS和HTML,然而,JS仍然会在很多情况下不工作(网络问题,脚本冲突等)。但是对于JavaScript,如果你总是记住和unobetructive的Javascript一起工作,不适用polyfill也没什么大不了。
最好的polyfill缺失API的方式是使用Modernizr 库以及它的子项目 YepNope. Modernizr 库允许您测试功能可用性,以便采取相应的行动。YepNope 是一个条件加载库。
下面是一个例子:
Modernizr.load({ // 这会测试您的浏览器是否支持HTML5表单验证API test : Modernizr.formvalidation, // 如果浏览器不支持它,则会加载以下polyfill nope : form-validation-API-polyfill.js, // 无论如何,你的核心App文件依赖于该API被加载 both : app.js, // 一旦加载了这两个文件,就会调用该函数来初始化应用程序 complete : function () { app.init(); } });
Modernizr 团队按照惯例维护着a list of great polyfills。仅仅按需使用即可。
Note: Modernizr还有其他很棒的功能可以帮助您处理unobstructive的JavaScript和优雅的降级技术。请阅读 Modernizr documentation.
尽管像Modernizr这样的脚本对性能非常敏感,但加载200千字节的polyfill仍然会影响程序的性能。这对旧式浏览器来说尤其重要,这些浏览器有处理速度非常慢的JavaScript引擎,让polyfills的执行对于用户来说变得很痛苦。性能本身就是一个主题,但旧式浏览器对它非常敏感:基本上,它们速度慢,需要的poliyfill越多,它们需要处理的JavaScript越多。与现代浏览器相比,它们承受双重负担。使用旧版浏览器测试你的代码,了解它们的实际表现。有时,放弃某些功能会带来更好的用户体验,而不是在所有浏览器中具有完全相同的功能。作为最后提醒,总是优先考虑用户。
正如你所看到的,处理旧式浏览器不仅仅是表单问题。而是一整套技术;但是掌握所有这些技术超出了本文的范围。
如果你阅读了HTML Forms guide中的所有文章,你应该可以放心的使用表单了。如果你想探索新技术,请帮助improve the guide.
{{PreviousMenuNext("Learn/HTML/Forms/Sending_forms_through_JavaScript", "Learn/HTML/Forms/Styling_HTML_forms", "Learn/HTML/Forms")}}