让你的网站在低版本浏览器上同样显示出色

本贴最后更新于 4125 天前,其中的信息可能已经天翻地覆

HTML5 的采用策略:一个浏览器也不放弃。

下载示例代码:http://code.msdn.microsoft.com/mag201109HTML5

HTML5 有许多激动人心的特性,有了新的标签、新的 CSS 能力和新的 JavaScript API,Web 的能力范围有了大的飞跃。除了浏览器厂商的士气高涨之外,令人激动的新功能列表几乎每天都在增加。从“nightly builds”(每夜都构建一版)到开发渠道发行版和正常的平台预览版,浏览器在飞速变化,世界各地Web开发人员们正在加入这个狂欢。

但是,尽管开发和浏览器社区正在把 HTML5 的喧嚣推到一个极度兴奋的高潮,网上的大多数人却不像我们一样使用最新的浏览器和最新版本。如果你是一个大型开发机构的Web开发人员或者是拥有庞大用户 群的大企业,那你对此可能很清楚。即使你为通过Web提供服务的小型机构或新创立的企业工作,你可能也要花上大量时间来确保自己的网站能够支持尽可能多的 浏览器和浏览器版本。

基于这一现实,很容易看出,HTML5 还谈不到它是否已为当今的使用做好准备,而是你是否为它做好了准备。例如,假设你用一些新的语法标签(例如

和)新建了一个页面,添加了一些新的 CSS 功能,例如圆角(border-radius)和阴影(box-shadow),甚至添加了一个元素在页面上绘制出一个 HTML5 标识。

在较新的浏览器上,例如 Internet Explorer 9、Firefox 4 及以上版本、或者 Google Chrome 上,这个页面的显示如图1所示。但如果尝试在 Internet Explorer 8 或更早的浏览器上加载页面,很有可能看到的是图2所示的效果:一个残缺不全的页面。


图1 使用 HTML5 语法、样式和元素的简单页面在 IE9 中显示的效果

图2 同一个页面,在IE8中显示时,没有样式,也没有

如果你在研究 HTML5 的所有强大功能却得到上述体验之后告诉自己说:最好还是等等,那么我不会对你有任何责怪。如果我问你准备好了吗?你很容易得出这样的结论:HTML5 还没有为你或你的用户做好准备。

在你决定等到2022年再考虑HTML5的之前,我建议你继续阅读本文的后面部分,我将向你提供一些实用的策略,让你现在就能采用HTML5技术,同时避免出现图2所示的糟糕的降级情况。我将从下面三个主题进行详细地介绍:

  • 功能检测与用户代理(UA)嗅探比较
  • 用JavaScript实现填补(Polyfill)
  • 优雅降级

这些应该可以教会你很多构建支持各种浏览器的网站所需要了解的知识。在本文结束时,你会拥有一个可靠的策略,可以充满自信、毫不犹豫地采用 HTML5 技术。你还会拥有一些工具在手,可以逐步地为新浏览器增强网站,同时更好地适应旧的浏览器。

功能检测的重要性

为了提供跨浏览器的稳定且一致的体验,开发人员经常需要获得一些关于用户浏览器的信息。以前的普遍做法是像下面这样用 JavaScript 检测这些信息:

varuserAgent = navigator.userAgent; if (userAgent.indexOf('MSIE') >= 0) {
  console.log("Hello, IE user");
} else if (userAgent.indexOf('Firefox') >= 0) {
  console.log("Hello, Firefox user");
} else if (userAgent.indexOf('Chrome') >= 0) {
  console.log("Hello, Chrome user");
}

这个技术称为用户代理(UA)嗅探,广泛地用于判断正在请求页面的是哪个浏览器。这里的思路是:知道了用户的浏览器(例如 IE7),就能在运行的时候决定启用或禁用网站的哪项功能。UA 嗅探就相当于对浏览器说:“你是谁?”(对 UA 嗅探以及其他检测技术的深入分析,请参阅 jibbering.com/faq/notes/detect-browser/。)

这种做法的问题在于,浏览器会撒谎。UA 字符串是一个用户可以配置的信息,并不会提供100%正确的浏览器信息。而且,随着这一技术的广泛采用,许多浏览器厂商在自己的 UA 字符串中增加了额外内容,用来欺骗脚本,让脚本对于实际使用的浏览器做出错误判断,从而避免检测。现在有些浏览器甚至提供小工具,允许用户只要轻轻点击几 下鼠标,就能修改 UA 字符串。

UA 嗅探的目的从来就不是确定用户的浏览器和版本。而且它肯定也不是为了在你不喜欢用户使用的浏览器时,让你可以告诉用户说“请下载另一个浏览器”——即使有 些人就是这样使用 UA 嗅探技术的。用户有权选择自己使用什么浏览器,开发人员的职责则是提供最可靠且一致的体验,不要把浏览器的偏好强加给用户。UA 嗅探的目标是让你能够准确地了解在用户当前的浏览器中,有哪些能力或功能可以利用。对浏览器本身的了解,只是获得这些信息的一个途径。

目前有一些 UA 嗅探的替代技术,其中一项正在日益流行的技术称为对象检测或功能检测。这两个术语多数时候可以互换使用,但本文统一使用“功能检测”(feature detection)。

功能检测的目标是判断某项功能或能力在用户当前的浏览器中是否受支持。如果 UA 嗅探是问浏览器“你是谁”,“功能检测”就是问浏览器“你能干什么”,这个问题更直接,对于根据条件向用户提供功能来说,这种方法也更可靠。如果功能检测 脚本实现正确,用户或浏览器将很难造假或错报功能支持。

手动功能检测

那么,与 UA 嗅探的示例相比,功能检测到底是什么样呢?为了回答这个问题,我们先来看看如果在 Internet Explorer 8 中查看前面的 HTML5 页面(如图1所示),如何解决出现的问题。这个页面的标签内容如代码段1所示。

    My Awesome Site    

My Awesome Site

An Article

Isn't this awesome?

代码段1 带有 HTML5 新语义标签的页面

图1图2所示,Internet Explorer 9 和 Internet Explorer 8 的显示效果有很大的差别。对于初学者来说,我的页面完全没有样式,因为这个页面的CSS并不存在。而且,页面底部丢失了好玩的 HTML5 盾牌。每个问题都可以轻松解决,而功能检测则是明确问题的第一步。

两个问题的原因都很简单:对于 Internet Explorer 8 来说,

、和都不是有效的 HTML 元素,所以无法使用。要解决问题,我们不用 UA 嗅探来判断所使用的浏览器/版本,而要通过 JavaScript 询问浏览器是否支持元素和它的 JavaScript API,对 Canvas 的功能检测如下所示:

!!document.createElement('canvas').getContext

这条语句做了好几件事:首先,它使用两个否定(!!)操作符强行将未定义的值显式地设为 false;然后,它手动新建一个canvas元素,并将它加到DOM中;最后,它调用 getContext 函数,这是元素的一个新函数,是通过 JavaScript 操纵 Canvas API 的途径。如果使用 IE9,则这条语句会返回 true。如果使用 IE8,则 getContext 会返回“undefined”(未定义),会被前面的两个否定操作符强行变为 false。

这是最基本的功能检测。利用这条语句以及其他类似语句,就有了查询浏览器所支持功能的更可靠方法。关于手动功能检测的更多信息,请参阅 diveintohtml5.info/everything.html

使用Modernizr进行功能检测

手动功能检测肯定是对UA嗅探的提高,但这种做法仍然需要你做大量工作来检测功能是否可用,以及在功能不存在的时候决定做什么。虽然 Canvas 示例很简单,只需要一行代码,但不是每个要检测的功能都这么简单——不同浏览器的检测代码也各不相同。例如,要检测是否支持前面使用的 CSS3 模块(border-radius和box-shadow)就有些麻烦。

值得庆幸的是,Modernizr (modernizr.com) 提供了更好的方法。Modernizr 是一个 JavaScript 库“……检测下一代 Web 技术(即源于 HTML5和 CSS3 规范的功能)的本地实现是否可用”。在页面上添加对 Modernizr 的引用可以提供四大功能:

  1. 全面列出支持的功能,智能地加入标签,从而实现 CSS 的条件定义。
  2. 一个 JavaScript 对象,方便进行基于脚本的功能检测。
  3. 在运行的时候将全部 HTML5 新标签加入 DOM,方便 IE8 和之前的 IE 浏览器(稍后就会知道不仅如此)。
  4. 一个脚本加载器,可以根据条件将 polyfill 加载到页面中。

本文对第1项不做进一步介绍,但鼓励你访问 modernizr.com 网站,学习这一功能及其余功能的文档。

上面的第2项功能,可以将下面的代码:

!!document.createElement('canvas').getContext

改为这行代码:

Modernizr.canvas

这行代码会返回一个布尔值,表明页面是否支持 Canvas 元素。使用 Modernizr 比自行执行功能检测的好处是,Modernizr 是一个经过良好测试、健壮的、广为采用的库,它已经完成了许多繁重的工作。Twitter、Google、Microsoft 以及无数其他机构和开发人员都在使用 Modernizr,你当然也可以使用。在 ASP.NET MVC 3 工具更新(2011年4月发布)中,Microsoft 甚至随新的 ASP.NET MVC 应用程序一起配备了 Modernizr。当然,我们迄今为止所做的,不过是检测是否支持元素。通过功能检测知道了浏览器是否支持某一功能之后, 接下来通常是创建一些条件逻辑,在功能不存在的时候阻止特定代码的执行或者换个路径来执行,例如:

if (Modernizr.canvas) { // 这里执行canvas代码。 }

根据附加的浏览器功能是否存在来给网站增加功能,这种做法称为“渐进式增强”,因为体验增强针对的能力更强的浏览器。另一方面是“优雅降 级”,即某项功能的缺失不会造成浏览器出错或发生故障,而是应该向用户提供一些削弱的功能或替代能力。对于旧版浏览器来说,不必将优雅降级作为默认选择。 在许多情况下,甚至可能不是最佳选择。相反,在 Modernizr 的帮助下,你通常可以使用许多可用的浏览器 polyfill,将类似于 HTML5 的功能添加到不支持 HTML5 的浏览器中。

什么是 Polyfill

根据 Modernizr 网站的说法,polyfill 是“在旧版浏览器上复制标准 API 的 JavaScript 补充”。“标准API”指的是 HTML5 技术或功能,例如 Canvas。“JavaScript补充”指的是可以动态地加载 JavaScript 代码或库,在不支持这些标准 API 的浏览器中模拟它们。例如,geolocation(地理位置)polyfill 可以在 navigator 对象上添加全局的 geolocation 对象,还能添加 getCurrentPosition 函数以及“坐标”回调对象,所有这些都是 W3C 地理位置 API 定义的对象和函数。因为 polyfill 模拟标准 API,所以能够以一种面向所有浏览器未来的方式针对这些 API 进行开发,最终目标是:一旦对这些 API 的支持变成绝对大多数,则可以方便地去掉 polyfill,无需做任何额外工作。

通过在页面上添加对 Modernizr 的引用,我就得到了与代码段1示例相关的 polyfill 的直接好处。页面显示没有样式,是因为 IE8 不认识

和标签。因为它不认识这些标签,所以没将它们加入DOM,而CSS选择元素要发挥样式作用,需要在 DOM 中有这些元素。

当我在页面上添加

  • CSS

    CSS(Cascading Style Sheet)“层叠样式表”是用于控制网页样式并允许将样式信息与网页内容分离的一种标记性语言。

    180 引用 • 447 回帖
  • HTML

    HTML5 是 HTML 下一个的主要修订版本,现在仍处于发展阶段。广义论及 HTML5 时,实际指的是包括 HTML、CSS 和 JavaScript 在内的一套技术组合。

    103 引用 • 294 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
Vanessa
我们终此一生,就是要摆脱他人的期待,找到真正的自己。

推荐标签 标签

  • ngrok

    ngrok 是一个反向代理,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道。

    7 引用 • 63 回帖 • 599 关注
  • 支付宝

    支付宝是全球领先的独立第三方支付平台,致力于为广大用户提供安全快速的电子支付/网上支付/安全支付/手机支付体验,及转账收款/水电煤缴费/信用卡还款/AA 收款等生活服务应用。

    29 引用 • 347 回帖 • 1 关注
  • WordPress

    WordPress 是一个使用 PHP 语言开发的博客平台,用户可以在支持 PHP 和 MySQL 数据库的服务器上架设自己的博客。也可以把 WordPress 当作一个内容管理系统(CMS)来使用。WordPress 是一个免费的开源项目,在 GNU 通用公共许可证(GPLv2)下授权发布。

    45 引用 • 113 回帖 • 309 关注
  • 导航

    各种网址链接、内容导航。

    37 引用 • 168 回帖
  • 面试

    面试造航母,上班拧螺丝。多面试,少加班。

    324 引用 • 1395 回帖 • 1 关注
  • 30Seconds

    📙 前端知识精选集,包含 HTML、CSS、JavaScript、React、Node、安全等方面,每天仅需 30 秒。

    • 精选常见面试题,帮助您准备下一次面试
    • 精选常见交互,帮助您拥有简洁酷炫的站点
    • 精选有用的 React 片段,帮助你获取最佳实践
    • 精选常见代码集,帮助您提高打码效率
    • 整理前端界的最新资讯,邀您一同探索新世界
    488 引用 • 383 回帖 • 5 关注
  • AngularJS

    AngularJS 诞生于 2009 年,由 Misko Hevery 等人创建,后为 Google 所收购。是一款优秀的前端 JS 框架,已经被用于 Google 的多款产品当中。AngularJS 有着诸多特性,最为核心的是:MVC、模块化、自动化双向数据绑定、语义化标签、依赖注入等。2.0 版本后已经改名为 Angular。

    12 引用 • 50 回帖 • 427 关注
  • 房星科技

    房星网,我们不和没有钱的程序员谈理想,我们要让程序员又有理想又有钱。我们有雄厚的房地产行业线下资源,遍布昆明全城的 100 家门店、四千地产经纪人是我们坚实的后盾。

    6 引用 • 141 回帖 • 561 关注
  • Logseq

    Logseq 是一个隐私优先、开源的知识库工具。

    Logseq is a joyful, open-source outliner that works on top of local plain-text Markdown and Org-mode files. Use it to write, organize and share your thoughts, keep your to-do list, and build your own digital garden.

    4 引用 • 55 回帖 • 12 关注
  • 小说

    小说是以刻画人物形象为中心,通过完整的故事情节和环境描写来反映社会生活的文学体裁。

    28 引用 • 108 回帖
  • BAE

    百度应用引擎(Baidu App Engine)提供了 PHP、Java、Python 的执行环境,以及云存储、消息服务、云数据库等全面的云服务。它可以让开发者实现自动地部署和管理应用,并且提供动态扩容和负载均衡的运行环境,让开发者不用考虑高成本的运维工作,只需专注于业务逻辑,大大降低了开发者学习和迁移的成本。

    19 引用 • 75 回帖 • 618 关注
  • 招聘

    哪里都缺人,哪里都不缺人。

    189 引用 • 1056 回帖
  • 快应用

    快应用 是基于手机硬件平台的新型应用形态;标准是由主流手机厂商组成的快应用联盟联合制定;快应用标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台;以平台化的生态模式对个人开发者和企业开发者全品类开放。

    15 引用 • 127 回帖 • 5 关注
  • V2EX

    V2EX 是创意工作者们的社区。这里目前汇聚了超过 400,000 名主要来自互联网行业、游戏行业和媒体行业的创意工作者。V2EX 希望能够成为创意工作者们的生活和事业的一部分。

    17 引用 • 236 回帖 • 417 关注
  • MyBatis

    MyBatis 本是 Apache 软件基金会 的一个开源项目 iBatis,2010 年这个项目由 Apache 软件基金会迁移到了 google code,并且改名为 MyBatis ,2013 年 11 月再次迁移到了 GitHub。

    170 引用 • 414 回帖 • 425 关注
  • 资讯

    资讯是用户因为及时地获得它并利用它而能够在相对短的时间内给自己带来价值的信息,资讯有时效性和地域性。

    53 引用 • 85 回帖
  • PostgreSQL

    PostgreSQL 是一款功能强大的企业级数据库系统,在 BSD 开源许可证下发布。

    22 引用 • 22 回帖 • 1 关注
  • CAP

    CAP 指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得。

    11 引用 • 5 回帖 • 567 关注
  • WebSocket

    WebSocket 是 HTML5 中定义的一种新协议,它实现了浏览器与服务器之间的全双工通信(full-duplex)。

    48 引用 • 206 回帖 • 394 关注
  • 友情链接

    确认过眼神后的灵魂连接,站在链在!

    24 引用 • 373 回帖 • 1 关注
  • Markdown

    Markdown 是一种轻量级标记语言,用户可使用纯文本编辑器来排版文档,最终通过 Markdown 引擎将文档转换为所需格式(比如 HTML、PDF 等)。

    164 引用 • 1456 回帖
  • Tomcat

    Tomcat 最早是由 Sun Microsystems 开发的一个 Servlet 容器,在 1999 年被捐献给 ASF(Apache Software Foundation),隶属于 Jakarta 项目,现在已经独立为一个顶级项目。Tomcat 主要实现了 JavaEE 中的 Servlet、JSP 规范,同时也提供 HTTP 服务,是市场上非常流行的 Java Web 容器。

    162 引用 • 529 回帖
  • ZeroNet

    ZeroNet 是一个基于比特币加密技术和 BT 网络技术的去中心化的、开放开源的网络和交流系统。

    1 引用 • 21 回帖 • 593 关注
  • Eclipse

    Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。

    75 引用 • 258 回帖 • 625 关注
  • 创造

    你创造的作品可能会帮助到很多人,如果是开源项目的话就更赞了!

    173 引用 • 990 回帖
  • Gzip

    gzip (GNU zip)是 GNU 自由软件的文件压缩程序。我们在 Linux 中经常会用到后缀为 .gz 的文件,它们就是 Gzip 格式的。现今已经成为互联网上使用非常普遍的一种数据压缩格式,或者说一种文件格式。

    9 引用 • 12 回帖 • 114 关注
  • CentOS

    CentOS(Community Enterprise Operating System)是 Linux 发行版之一,它是来自于 Red Hat Enterprise Linux 依照开放源代码规定释出的源代码所编译而成。由于出自同样的源代码,因此有些要求高度稳定的服务器以 CentOS 替代商业版的 Red Hat Enterprise Linux 使用。两者的不同在于 CentOS 并不包含封闭源代码软件。

    238 引用 • 224 回帖 • 1 关注