/ Browser

构建现代站点且同时支持旧版 IE 的 20 个提示

作者:Dave Methvin    Rey Bango

过去几年,我们花了大量时间与 Web 开发人员交流,而我们最常听到的一件事就是,构建适用于各种浏览器版本和设备的站点非常困难。在为 jQuery 项目构建代码时,我们亲身经历了这种困难。为此,我们编撰了排名前 20 的编码模式和实践列表,这些都是我们在参加了无数的会议并阅读了数百本教程后挑选出来的。我们希望在您构建站点时,它们能帮您节省一些时间(并解决难题)。

跨浏览器基础

  1. 站点在所有浏览器中的呈现方式不必相同

    开发人员普遍关注的一个问题是要确保其站点在所有浏览器(包括非现代浏览器)中的呈现效果一致。其实并不一定必须这么做。更好的方法是考虑向使用非现代浏览器的用户提供实用且流畅的用户体验,同时向使用现代浏览器的用户提供更丰富的 UI,以此来逐步增强您的站点。
  2. 从可靠的模板着手以简化开发。

    许多这类提示已构建到 HTML5 Boilerplate 之类的项目模板中,可帮助您节省一些时间。对于面向现代浏览器的项目以及需要获得低至 IE6 的旧版浏览器支持的项目,这些规则同等地有效。
  3. 关注稳定标准

    每当出现一个全新的的功能时,总是让人欣喜,但是其中有些功能仍处于实验阶段,其规范仍在开发中。务必要记住,处于规范开发早期阶段的功能很可能发生变化,这可能会影响您站点的稳定性以及用户体验。通过关注稳定标准,您将确保客户能获得所期待的体验,您的站点也更易于维护。
  4. 使用 IE Compat Inspector 帮助将站点迁移到基于标准的代码

    标准是 Internet Explorer 10 的核心部分,对 IE 工程团队而言,帮助开发人员迁移其代码以便利用这一优势是非常重要的。为此,他们创建了 IE Compat Inspector,它可以实时分析站点,查明常见问题并提供解决方案。通过在您的代码中包含简单的 JavaScript 文件,您将可以在页面右上角看到统计结果。此外,它还可以集成到 Fiddler HTTP 分析工具中。
  5. 慎用polyfill 和 shim

    如果您需要在所有浏览器中提供相同的体验,则polyfill 和 shim提供的代码和标记可帮助模仿基于标准的 API 和功能。要记住的关键一点是,您需要完全的检查代码,以确保代码满足您的用例,并且您可以支持代码不断发展。
  6. 在开发的同时在多个浏览器中进行测试。

    虽然现代浏览器比以往任何时候都更接近单一标准,但是仍然存在差异。在开发过程中不定期地进行多浏览器健全性检查,可以确保严重的跨浏览器问题不会在最后一刻,甚至在完全公开后突然出现。请务必检查每个浏览器的控制台(例如 IE 中的 F12 开发人员工具),确认是否会有出现任何错误或警告消息。对于没有内置控制台的旧版浏览器(例如 IE7),您可以使用 Firebug Lite 来提供控制台。或者,您可以使用跨浏览器托管测试解决方案,例如 BrowserStack。
  7. 在构建过程中使用工具来检查错误并压缩文件。

    有一组出色的构建工具(例如 HTML 验证程序CSS 验证程序Uglify 和 JSHint,或者 GruntJS)可以找到潜在问题、强制实施项目代码标准,并减少文件大小以改善性能。如果您的 IDE 或代码编辑器提供相关支持,则这些步骤并不会是一个障碍。例如,Visual Studio 在其构建过程中可以运行外部工具,并合并/压缩脚本文件

HTML

  1. 始终使用基于标准的文档类型来避免 Quirks 模式。

    从 <!DOCTYPE html> 入手。现代 Web 中容不下 Quirks 模式,该模式最初旨在使 20 世纪 90 年代中期的网页可用于世纪交替的“现代”浏览器(例如 IE6 和 Firefox 2)中。如今,大多数网页在 Quirks 模式下会意外关闭,原因是无效的文档类型或文档类型之前的多余文本。这可能造成难以调试的奇怪布局问题。
  2. 了解 HTML5 标记的向后兼容性限制。

    新的 HTML5 标签(例如 <section>、<header> 和 <footer>)改进了标签的语义,但是需要特殊的“shiv”脚本以在 Internet Explorer 6、7 和 8 中运行,否则这些标签就无法识别。如果页面需要在禁用脚本的旧版浏览器中运行,则无法使用新的 HTML5 标签。对于这些情况,使用普通的 <div> 元素和类通常是更安全的做法。
  3. 将 CSS 文件引用置于 HTML 文件顶部。

    将 CSS 文件置于正文中可能导致浏览器在 CSS 已加载之前显示空白页面。CSS 文件应当置于 HTML 文档头部,以允许浏览器尽早开始读取这些文件。
  4. 将 JavaScript 文件引用置于 HTML 文件底部。

    浏览器必须先检索、分析并执行以 HTML 标签表示的脚本文件,然后才能继续分析文件的其余部分,以防 JavaScript 向页面中写入新标签。脚本位于底部时,则在脚本完成前,浏览器往往也可以渲染页面,这样,用户就会觉得页面加载更快。
  5. 避免 HTML 标记中出现内联 JavaScript 标签。

    与外部脚本引用一样,内联脚本需要浏览器停止分析 HTML,并且还会阻止并行下载页面上的其他资源。这可能会严重降低页面的初始加载速度,并让用户体验到可怕的“空白页面”。标记周围分布的脚本也更难维护
  6. 不要在 HTML 标记中使用内联 JavaScript 事件。

    示例包括 <button onclick="validate()">Validate</button>。该做法破坏了结构、样式和行为之间应该存在的彻底分离。此外,如果脚本在文件底部加载,则用户可以与页面交互并触发尝试调用尚未加载的脚本的事件,从而导致出错。

CSS

  1. 了解并使用 CSS 级联规则。

    简单的 ID 和类选择器十分有用,但是以独占方式使用它们则意味着有了不必要的 ID 和类后,标记会变得更乱、更加不可重用。将标签、后代、子级、同级和属性选择器与一小部分 ID 和类结合使用可以使标记和 CSS 都变得更简单、更通用。无论如何都要避免使用“!important”规则。
  2. 给特定于供应商的 CSS 属性全部加前缀,以使其不会过时。

    随着新草案标准不断进步,浏览器供应商有时会通过添加私有前缀的属性支持来领先于标准。为了确保 CSS 将来继续有效,请使用所有供应商前缀的名称以及没有前缀的名称。本篇博客文章提供了普通 JavaScript 的替代项。
  3. 使用有效的 CSS 规则(而不是 CSS hack)来解决兼容性问题。

    CSS hack不可靠,因为浏览器更新后可能会导致hack失败。取而代之,应尝试向可用于样式表规则中的 html 或正文标记中添加特定于版本的类条件注释也可用于仅在有需要的版本中包含特定于浏览器的 CSS 文件。

JavaScript

  1. 始终首选功能检测,而非浏览器 (navigator.userAgent) 检测。

    userAgent 字符串不能有效指示某个特定功能(或 bug)是否存在。此外,大部分解释 userAgent 的代码也没有解释正确。例如,某个浏览器探查库要求主要版本是个位数,因此它会将 Firefox 15 报告为 Firefox 1,将 IE 10 报告为 IE 1!更可靠的方法是直接检测功能或问题,然后将其用作代码分支的决策标准。根据我们的建议,Modernizr 是实施功能检测的最轻松方法。
  2. 在文档就绪时,运行尽可能小的脚本。

    系统加载页面上的 HTML 后,诸如 jQuery's $(document).ready() 之类的技术会使脚本的运行变得很轻松,而这通常是脚本可以安全运行的最早时刻。但是,此时运行大量复杂的脚本可能使页面显示迟缓,并阻止用户与页面进行即时交互。通常,工具提示或对话框等内容的初始化可延迟到实际需要显示该项目为止,不会有明显的不连续效果。
  3. 如果 AJAX 请求对用户与页面的交互很关键,则尽早启动这些请求。

    由于 AJAX 请求可能耗时较长,因此不必等待 HTML 页面就绪后才启动该请求。相反,应将 $(document).ready() 调用置于 AJAX 完成函数中。
  4. 延迟加载非必要的脚本(例如 Facebook Like、Google +1、Twitter)。

    每个人都希望自己的页面在社交网络上走红,但是社交网络脚本往往很大,可能导致对用户的响应变迟缓。在请求这些脚本之前等待页面加载完成,这样可以使页面响应更快。更好的做法是重新考虑这些按钮是否必要,以及它们是否能提升页面的总体体验。
via 构建现代站点且同时支持旧版 IE 的 20 个提示

Dave Methvin @davemethvin

Dave Methvin 是 jQuery 基金会主席、jQuery Core 团队首席开发人员,2006 年加入 jQuery 社区。自 1996 年起,他一直致力于创建 JavaScript 和 HTML Web 解决方案。http://blog.methvin.com

Rey Bango @reybango

Rey Bango 是 Microsoft 针对所有 Web 标准的技术传达者。如果他不在编码,就是在演讲写博客发推文(等等)。他之前是jQuery Core 团队成员,曾创立ScriptJunkie,并为 Ajaxian.com 写过东西。http://blog.reybango.com/