--- 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 --- <div>{{LearnSidebar}}{{PreviousMenuNext("Learn/HTML/Forms/Sending_forms_through_JavaScript", "Learn/HTML/Forms/Styling_HTML_forms", "Learn/HTML/Forms")}}</div> <p class="summary">所有 web 开发者很快就会(有时候是痛苦地)发现网络是一个令人不快的地方。我们碰到的最恶毒的诅咒是旧式浏览器。好吧,让我们承认吧,当我们提到 “旧式浏览器” 时,脑海中出现就是 老版本的 Internet Explorer ……但是,这远远不是全部。只发布一年的 Firefox 比如 <a href="http://www.mozilla.org/en-US/firefox/organizations/">the ESR version</a> 也是旧式浏览器。那么,在移动世界呢?当浏览器和 OS(操作系统) 都不能更新时?是的,有非常多老版本的 Android 手机或 iPhone 没有更新到最新的浏览器。它们同样是旧式浏览器。</p> <p>可悲的是,处理这些传统浏览器的问题是工作的一部分。幸运的是,有一些技巧可以帮助您解决旧式浏览器导致的大约80%的问题。</p> <h2 id="了解这些问题">了解这些问题</h2> <p>实际上,最重要的事情是阅读那些浏览器的文档,并尝试理解通用的(解决)模式。例如,在许多情况下,HTML表单是否支持CSS是最大的问题。这是正确的开始,只需要检查你想用的元素或接口是否支持CSS即可。MDN有一个关于包含HTML中可用的元素、属性或API的兼容表单可查。 此外,仍有其他一些非常有用的资源:</p> <h3 id="浏览器厂商的文档">浏览器厂商的文档</h3> <ul> <li>Mozilla: 直接查看MDN即可</li> <li>Microsoft: <a href="http://msdn.microsoft.com/en-us/library/ff410218%28v=vs.85%29.aspx" rel="external">Internet Explorer Standards Support Documentation</a></li> <li>WebKit: 由于有多个版本的引擎,稍微有点棘手. <ul> <li><a href="https://www.webkit.org/blog/" rel="external">The WebKit blog</a> 和 <a href="http://planet.webkit.org/" rel="external">Planet WebKit</a> 聚合了Webki核心开发者的最佳文章.</li> <li><a href="https://www.chromestatus.com/features">Chrome platform status site</a> 也十分重要</li> <li>同样重要的是 <a href="https://developer.apple.com/technologies/safari/" rel="external">the Apple web site.</a></li> </ul> </li> </ul> <h3 id="独立文档">独立文档</h3> <ul> <li><a href="http://caniuse.com" rel="external">Can I Use</a> 有关于是否支持最新技术的信息.</li> <li><a href="http://www.quirksmode.org" rel="external">Quirks Mode</a> 是关于浏览器兼容性的精彩资源. <a href="http://www.quirksmode.org/mobile/" rel="external">mobile部分</a>是当前最好的内容之一.</li> <li><a href="http://positioniseverything.net/" rel="external">Position Is Everything</a> 关于旧式浏览器渲染bug以及解决办法(如果有)的最佳资源.</li> <li><a href="http://mobilehtml5.org" rel="external">Mobile HTML5</a> 有关于大量手机浏览器的兼容性信息,而不仅仅是是前五名(包括诺基亚,亚马逊和黑莓).</li> </ul> <h2 id="让事情变得更简单">让事情变得更简单</h2> <p>由于<a href="/en-US/docs/HTML/Forms" title="/en-US/docs/HTML/Forms">HTML forms</a> 包含复杂的交互,所以有一条法则: <a href="http://en.wikipedia.org/wiki/KISS_principle" rel="external">keep it as simple as possible</a>。很多时候,我们想让表单更美观或想使用更高级的技术,然而,构建高效的HTML表单不只是设计和技术问题。记得花时间读一下这篇文章t <a href="http://www.uxforthemasses.com/forms-usability/" rel="external">forms usability on UX For The Masses</a>.</p> <h3 id="优雅地降级(Graceful_degradation)是web开发者最好的朋友">优雅地降级(Graceful degradation)是web开发者最好的朋友</h3> <p><a href="http://www.sitepoint.com/progressive-enhancement-graceful-degradation-choice/" rel="external">Graceful degradation and progressive enhancement</a> 是一个开发模式,它允许你通过同时支持多种浏览器来构建优秀内容。当你为现代浏览器构建内容时,你想确保它能在旧式浏览器中以某种方式工作,这就是优雅地降级(graceful degradation).</p> <p>让我们看一些关于HTML表单的例子:</p> <h4 id="HTML_input_类型">HTML input 类型</h4> <p>HTML5引入的新input类型十分酷,因为他们的降级(degrade)是高度可预测的。如果一个浏览器不能理解 {{HTMLElement("input")}}元素的 {{htmlattrxref("type","input")}} 属性, 它将会后退到<code>text</code>一样的行为。</p> <pre class="brush: html"><label for="myColor"> Pick a color <input type="color" id="myColor" name="color"> </label></pre> <table> <thead> <tr> <th scope="col" style="text-align: center;">Chrome 24</th> <th scope="col" style="text-align: center;">Firefox 18</th> </tr> </thead> <tbody> <tr> <th style="text-align: center;"><img alt="Screen shot of the color input on Chrome for Mac OSX" src="/files/4575/color-fallback-chrome.png" style="height: 35px; width: 139px;"></th> <th style="text-align: center;"><img alt="Screen shot of the color input on Firefox for Mac OSX" src="/files/4577/color-fallback-firefox.png" style="height: 30px; width: 245px;"></th> </tr> </tbody> </table> <h4 id="CSS_属性选择器">CSS 属性选择器</h4> <p><a href="/en-US/docs/CSS/Attribute_selectors" title="/en-US/docs/CSS/Attribute_selectors">CSS属性选择器 </a> 在 <a href="/en-US/docs/HTML/Forms" title="/en-US/docs/HTML/Forms">HTML Forms</a> 中十分有用,然而旧式浏览器不支持. 在那种情形下,一般会习惯性使用等价的class:</p> <pre class="brush: html"><input type="number" class="number"></pre> <pre class="brush: css">input[type=number] { /* 这在一些浏览器中是不能执行的 */ } input.number { /* 可以在任何浏览器中执行 */ }</pre> <p>注意下面的写法没有用(由于它是重复的),在某些浏览器中会失败:</p> <pre class="brush: css">input[type=number], input.number { /* 在某些浏览器中,这可能会失败,因为如果他们不理解其中任何一个选择器,则跳过整个规则 */ }</pre> <h4 id="表单按钮">表单按钮</h4> <p>有两种定义HTML表单按钮的方式:</p> <ul> <li>{{HTMLElement("input")}} 元素使用{{htmlattrxref("type","input")}} 属性并设置其值为<code>button</code>, <code>submit</code>, <code>reset</code> or <code>image</code></li> <li>{{HTMLElement("button")}} 元素</li> </ul> <p>如果你想通过元素选择器在按钮上应用CSS的话,采用 {{HTMLElement("input")}} 元素的方式会让事情变得稍微有点复杂:</p> <pre class="brush: html"><input type="button" class="button" value="click me"></pre> <pre class="brush: css">input { /* 此规则关闭了input元素定义的按钮的默认渲染样式 */ border: 1px solid #CCC; } input.button { /* 这条规则不会恢复默认渲染*/ border: none; } input.button { /* 这条也不会(恢复)! 实际上在浏览器中没有标准方式实现这一目标 */ border: auto; }</pre> <p>{{HTMLElement("button")}} 元素有两个问题令人困扰:</p> <ul> <li>在某些旧版本的IE浏览器中有bug。当用户点击按钮时,它不是发送{{htmlattrxref("value","button")}}属性中的内容,而是发送 {{HTMLElement("button")}} 的开闭标签之间的HTML内容. 如果我们想发送值时,这是一个问题,例如发送的处理数据依赖于用户点击不同的按钮时.</li> <li>一些旧浏览器不使用<code>submit</code> 作为 {{htmlattrxref("type","button")}} 属性的默认值, 所以建议总是在{{HTMLElement("button")}} 元素上设置设置 {{htmlattrxref("type","button")}} 属性.</li> </ul> <pre class="brush: html"><!-- 某些情形下,点击按钮将发送 "<em>Do A</em>" 而不是值"A" --> <button type="submit" name="IWantTo" value="A"> <em>Do A</em> </button></pre> <p>给予你的工程限制来选择上述任一种解决方案。</p> <h3 id="让我们过一遍CSS">让我们过一遍CSS</h3> <p>HTML表单和旧式浏览器最大的问题是CSS的兼容性。正如你可以从这篇文章 <a href="/en-US/docs/Property_compatibility_table_for_form_widgets" title="/en-US/docs/Property_compatibility_table_for_form_widgets">Property compatibility table for form widgets</a> 中看到的复杂性, 它非常的困难。即使仍然可以对文本元素(如大小、字体颜色等)进行一些调整,但那样做会有副作用。最好的办法还是不要美化HTML表单小组件。但你仍然可以将样式应用到表单周围的项目上。如果你是一个专业人士,并且你的客户需要那么做,在这种情况下,你可以研究一些硬技能,如 <a href="/en-US/docs/HTML/Forms/How_to_build_custom_form_widgets" title="/en-US/docs/HTML/Forms/How_to_build_custom_form_widgets">rebuilding widgets with JavaScript</a>。但在那种情况下,最好还是毫不犹豫的<a href="http://www.smashingmagazine.com/2011/11/03/but-the-client-wants-ie-6-support/" rel="external">让客户收回这些愚蠢的决定</a>。</p> <h2 id="功能检测和模拟(polyfills)">功能检测和模拟(polyfills)</h2> <p>尽管JavaScript在现代浏览中是非常棒的技术,但在旧式浏览器中可能存在很多的问题。</p> <h3 id="Unobtrusive_JavaScript">Unobtrusive JavaScript</h3> <p>API的兼容性是最大的问题。由于这个原因,与"不引人注意的(unobtrusive)" JavaScript一起工作被认为是最佳实践(译者注:此处意思是说没有/忽略JS或JS出了问题也能工作)。这个开发模式定义了两个需求:</p> <ul> <li>结构和行为之间的严格隔离</li> <li>如果代码出错,内容和基本功能必须保持可访问和可用状态</li> </ul> <p><a href="http://docs.webplatform.org/wiki/concepts/programming/the_principles_of_unobtrusive_javascript" rel="external">The principles of unobtrusive JavaScript</a> (最早是由Peter-Paul Koch为 Dev.Opera.com 所撰写,现在已转移到 Docs.WebPlatform.org) 同样阐述了上述观点。</p> <h3 id="Modernizr_库">Modernizr 库</h3> <p>有很多情形,好的"polyfill"能通过提供缺少的API以提供帮助。一个 <a href="http://remysharp.com/2010/10/08/what-is-a-polyfill/" rel="external">polyfill</a> 是一些JavaScript(脚本) 用于填补旧式浏览器中的功能缺失。虽然它们可以用来改进对任何功能的支持,并且使用它们Nederland风险小于CSS和HTML,然而,JS仍然会在很多情况下不工作(网络问题,脚本冲突等)。但是对于JavaScript,如果你总是记住和unobetructive的Javascript一起工作,不适用polyfill也没什么大不了。</p> <p>最好的polyfill缺失API的方式是使用<a href="http://modernizr.com" rel="external">Modernizr</a> 库以及它的子项目 <a href="http://yepnopejs.com" rel="external">YepNope</a>. Modernizr 库允许您测试功能可用性,以便采取相应的行动。YepNope 是一个条件加载库。</p> <p>下面是一个例子:</p> <pre class="brush: js">Modernizr.load({ // 这会测试您的浏览器是否支持HTML5表单验证API test : Modernizr.formvalidation, // 如果浏览器不支持它,则会加载以下polyfill nope : form-validation-API-polyfill.js, // 无论如何,你的核心App文件依赖于该API被加载 both : app.js, // 一旦加载了这两个文件,就会调用该函数来初始化应用程序 complete : function () { app.init(); } });</pre> <p>Modernizr 团队按照惯例维护着<a href="https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills" rel="external">a list of great polyfills</a>。仅仅按需使用即可。</p> <div class="note"> <p><strong>Note:</strong> Modernizr还有其他很棒的功能可以帮助您处理unobstructive的JavaScript和优雅的降级技术。请阅读 <a href="http://modernizr.com/docs/" rel="external">Modernizr documentation</a>.</p> </div> <h3 id="注意性能">注意性能</h3> <p>尽管像Modernizr这样的脚本对性能非常敏感,但加载200千字节的polyfill仍然会影响程序的性能。这对旧式浏览器来说尤其重要,这些浏览器有处理速度非常慢的JavaScript引擎,让polyfills的执行对于用户来说变得很痛苦。性能本身就是一个主题,但旧式浏览器对它非常敏感:基本上,它们速度慢,需要的poliyfill越多,它们需要处理的JavaScript越多。与现代浏览器相比,它们承受双重负担。使用旧版浏览器测试你的代码,了解它们的实际表现。有时,放弃某些功能会带来更好的用户体验,而不是在所有浏览器中具有完全相同的功能。作为最后提醒,总是优先考虑用户。</p> <h2 id="总结">总结</h2> <p>正如你所看到的,处理旧式浏览器不仅仅是表单问题。而是一整套技术;但是掌握所有这些技术超出了本文的范围。</p> <p>如果你阅读了<a href="/en-US/docs/HTML/Forms" title="/en-US/docs/HTML/Forms">HTML Forms guide</a>中的所有文章,你应该可以放心的使用表单了。如果你想探索新技术,请帮助<a href="/en-US/docs/Project:How_to_help" title="/en-US/docs/Project:How_to_help">improve the guide</a>.</p> <p>{{PreviousMenuNext("Learn/HTML/Forms/Sending_forms_through_JavaScript", "Learn/HTML/Forms/Styling_HTML_forms", "Learn/HTML/Forms")}}</p> <p> </p> <h2 id="In_this_module">In this module</h2> <ul> <li><a href="/en-US/docs/Learn/HTML/Forms/Your_first_HTML_form">Your first HTML form</a></li> <li><a href="/en-US/docs/Learn/HTML/Forms/How_to_structure_an_HTML_form">How to structure an HTML form</a></li> <li><a href="/en-US/docs/Learn/HTML/Forms/The_native_form_widgets">The native form widgets</a></li> <li><a href="/en-US/docs/Learn/HTML/Forms/Sending_and_retrieving_form_data">Sending form data</a></li> <li><a href="/en-US/docs/Learn/HTML/Forms/Form_validation">Form data validation</a></li> <li><a href="/en-US/docs/Learn/HTML/Forms/How_to_build_custom_form_widgets">How to build custom form widgets</a></li> <li><a href="/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript">Sending forms through JavaScript</a></li> <li>旧式浏览器中的HTML表单使用</li> <li><a href="/en-US/docs/Learn/HTML/Forms/Styling_HTML_forms">Styling HTML forms</a></li> <li><a href="/en-US/docs/Learn/HTML/Forms/Advanced_styling_for_HTML_forms">Advanced styling for HTML forms</a></li> <li><a href="/en-US/docs/Learn/HTML/Forms/Property_compatibility_table_for_form_widgets">Property compatibility table for form widgets</a></li> </ul> <p> </p>