提供行业解决方案

别再纠结了!尽管把你的烦恼交给我们吧,我们会将问题转化为一整套解决方案提供给你!方案的前期咨询根本不需你花一分钱。还不马上咨询?

提供软件客制服务

或许一套通用软件就能让你从烦恼中解脱出来,那就先到我们的软件产品仓库中选一款吧!我们还可以为你提供现有软件的扩展定制,即客户化定制。

提供软件实施服务

购买软件与汉堡包不同,软件产品和软件实施相结合才能发挥作用!没有良好的软件实施,必败!而采用我们的方案或产品,免费获得软件实施支持。

提供网站建设服务

坚持用心建站! 您只需告知所需要到达的终点,我们将带你一起穿越网站策划、平面设计、页面制作、程序开发和后期维护,享受全程的贴心服务。

提供网站维护服务

何必专门招人负责网站维护呢?你可能反驳招人能兼干其他工作,但是这样就不够专注。而我们提供的网站后期维护更专业,更专注,更划算。

51. 平稳退化对渐进增强

引言

在本篇教程中,我们将讨论两种开发方法之间的差别:功能衰减和渐进增强。下面是其简单定义:

功能衰减
作为一种确保某种产品的可用性的安全措施,功能衰减可以为你的功能提供一种替换版本,或让用户意识到该产品的缺点。
渐进增强
渐进增强是从一个功能可用的基本版本出发,然后逐步增加用户体验的丰富程度,并在应用增强功能之前先测试对该功能的支持性。

你可能会觉得这两种方法听起来非常相似,而且它们的效果也应该是几乎一样的,但这两种方法之间的确有需要加以注意的差别,下面我们就会对这个问题进行讨论。

我们首先会说明为什么需要这两种技术。然后我们会关注一下更深层次的定义,本文还展示了一些实际案例,再接下来是这两个概念之间的对比,以及讨论在什么时候该使用哪一种方法。我们先来说明为什么 Web 开发需要着两种开发方法。

 

本文结构如下:

“Mobilis in mobile”——迁入一个不断变化的环境中

就像“海底两万里”中的尼莫船长一样, Web 开发者们也发现他们自己处在一个不断变化的环境中,这个环境可能对我们想要实现的东西不太友好。

Web 在发明和定义之初,就是要能在任何显示设备中使用,而且可以使用任何语言,及在你想要的任何地方使用。终端用户只期望一件事,那就是他们所使用的浏览设备可以触及网络,并能理解用来传递信息的协议——http,https,ftp,等等。

这就意味着我们不能对我们的终端用户的设置和设备能力存有任何假设。我们还可以很肯定的是,作为开发者,我们对网络的理解跟我们想要触及的人群完全不一样。

你不能强制用户进行技术升级以获取互联网上的内容。个人用户和公司用户会倾向于待在一个确定的环境中,他们不会仅仅因为我们的希望就选择改变或升级。许多人只想使用网络,并不会去注意其背后的技术——他们所期望的只是获取我们所承诺提供的内容。让用户的系统保持在最新状态,这是操作系统和浏览器开发商的事情——作为 Web 开发者的我们对此没有任何发言权。

所有这些导致了一个非常脆弱的开发环境,比如某些办公室的默认配置是9年以前的老式浏览器,而且脚本和插件都是禁用的(由于安全性的原因),低分辨率的显示器,还有仅仅只够运行 Office 软件的计算机,这样的办公室环境是很常见的。

现在我们可以转头走掉,并声称这样的公司是“坐失良机”的,试图支持那些过时的技术是没有意义的。但这种态度可能会导致我们忽视这些人群,而他们可能对于我们产品的成功与否是至关重要的。在许多情况下他们没有权限改变自己的技术配置。在涉及到可访问性的时候,这些问题就更加地显而易见了:一个诵读困难的终端用户没办法理解我们那些复杂的说明,而一个盲人用户也不能“点击绿色按钮以继续”,尽管我们已经下令说这对于使用我们的系统而言是必要的。

我们要跟未知打交道,我们需要找到一种方法来保证我们的产品正常运行。这就是功能衰减和渐进增强派上用场的地方。

功能衰减和渐进增强

前面我们已经给出了关于这两者的一个简单的定义;在这一部分中我会给出更具有技术性的定义,并探讨对这些方法论进行网页开发到底有什么意义。

功能衰减是创建 Web 功能的一种方法,通过这种方法,如果用户使用的是先进的现代浏览器中,则网站能提供高水平的用户体验;如果用户使用的是较老式的浏览器,网站也能柔性地衰减到一个较低水平的用户体验。这个较低的水平对于网站用户来说,使用起来不那么美观,但它仍然能为用户提供所需的基本功能;对这些用户来说你的网站也不会变得不可用。

渐进增强也是类似的,但它是以另一种方式来实现这个目的的。你是从建立一个基础水平的用户体验开始的,所有的浏览器在渲染你的网站时都能提供这种水平的体验;不过你还会在此基础上加入更高级的功能,支持这些功能的浏览器会自动使用这些功能。

换句话说,功能衰减是从复杂的现状开始,并试图减少用户体验的供给,而渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要。功能衰减意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带。

功能衰减对渐进增强的一个简单示例

我们来看一个例子,这个示例展示了两种实现方式,一种利用渐进增强,而另一种利用功能衰减。

“打印本页面”链接

按理说,允许用户打印当前文档的链接是没什么用处的——点击浏览器中的打印机图标也可以达到同样的效果。然而用户测试表明,作为预订过程的最后一个步骤(比如在某个航空公司的网站上),这些链接是一种不错的可供用户进行重新确认的方式,值得一用。通过这些链接,用户会感觉自己拥有控制权,而且也会觉得这样就完成了自己开头要做的事情。

“打印本页面”链接的问题在于,我们无法用 HTML 来链接到浏览器中的打印按钮——你得用 JavaScript 来实现这一点。在 JavaScript 中这是很容易的——浏览器的 window 对象有一个 print() 方法,可以调用此方法来启动打印输出。实现这一点的最常见的方法可能就是使用 javascript: 伪协议了:

<p id="printthis">
  <a href="javascript:windowprint()">Print this page</a>
</p>

这段代码只有在 JavaScript 可用,同时也处于启用状态,并且浏览器支持print 命令的情况下才有效。如果 JavaScript 不可用(比如说在某些移动设备上),这个链接就无法工作——点击该链接不会出现任何反应。这就导致了一个问题,就是作为网站开发者,你可是向你的访客承诺了提供这个功能的。如果他们点击这个链接,而该链接完全没有用的话,用户们就会觉得很困惑,还会觉得被欺骗了,他们就有权谴责你提供了不好的用户体验。

为了改善这个问题,网站开发师们一般会利用功能衰减的方法:告诉用户该链接可能无法使用以及无法使用的原因,可能还会建议一种替代方案来帮助用户达成自己想要做的事情。实现这一点的常用技巧就是利用 noscript 元素。在这个元素内部的一切内容都会在 JavaScript 不可用的时候显示给终端用户。在我们这个例子中,可以像下面这样:

<p id="printthis">
  <a href="javascript:windowprint()">Print this page</a>
</p>
<noscript>
  <p class="scriptwarning">
    Printing the page requires  JavaScript  to be enabled. 
    Please turn it on in your browser.
  </p>
</noscript>

这就是柔性地衰减——我们向用户说明有些地方出问题了,并告知他们如何解决这个问题。然而,这样做的前提是假定你网站的用户都:

  • 知道什么是 JavaScript
  • 知道如何启用 JavaScript
  • 拥有启用 JavaScript 的权利
  • 乐意启用 JavaScript 以打印文档

下面的方法可能要稍微好些:

<p id="printthis">
  <a href="javascript:windowprint()">Print this page</a>
</p>
<noscript>
  <p class="scriptwarning">
    Print a copy of your confirmation. 
    Select the "Print" icon in your browser,
    or select "Print" from the "File" menu.
  </p>
</noscript>

这段代码解决了上面提到的部分问题,但它仍有前提假设,就是浏览器的打印功能在所有的浏览器中都是完全一样的。可是事实情况并非如此——这类方法的问题在于,我们提供了一些功能,但同时我们完全知道它可能无法运行,然后我们还得自己对其加以说明。从技术上讲“打印本页”按钮是没必要的,因此对于同一个问题,渐进增强的方法就用不着假定打印功能可以运行。

如果我们要用渐进增强来解决这个问题,第一步就是找出是否存在一种不用脚本的打印当前页面的方法。实际上并不存在,这说明了链接不是合适的的 HTML 元素。如果你想要提供一种仅当 JavaScript 可用时才能运行的功能的话,你就可以使用按钮:从定义上讲,按钮就是用来支持脚本功能的。W3C 的规范中说道:

按钮:按钮并没有默认的行为。每个按钮都可能有与该元素的事件属性相关联的客户端脚本。当某个事件发生(比如,用户按下该按钮,松开该按钮,等等)的时候,相关联的脚本就会被触发。

第二步就是不要假设用户的 JavaScript 是启用的,不能假设他们的浏览器具有打印功能。我们要做的只是坦白地告诉用户他们需要打印该文档,并将“如何打印”这个问题留给用户自己去解决:

<p id="printthis">Thank you for your order. Please print this page for your records.</p>

这个方法不管在什么情况下都有效。我们可以在浏览器支持 JavaScript 的时候用非干扰性的 JavaScript 来添加一个打印按钮:

<p id="printthis">Thank you for your order. Please print this page for your records.</p>
<script type="text/javascript">
(function(){
  if(document.getElementById){
    var pt = document.getElementById('printthis');
    if(pt && typeof window.print === 'function'){
      var but = document.createElement('input');
      but.setAttribute('type','button');
      but.setAttribute('value','Print this now');
      but.onclick = function(){
        window.print();
      };
      pt.appendChild(but);
    }
  }
})();
</script>

注意看这个脚本防御性有多强——我们什么前提假设都不需要。

  • 通过将整个功能封装在一个匿名函数中,并立即对其进行执行——这就是(function(){})() 所做的工作——我们就不会遗留下任何全局变量了。
  • 我们进行了 DOM 支持性测试,并尝试获取我们想要添加按钮的那个元素。
  • 然后我们对该元素是否存在,以及浏览器是否有 window 对象和 print 方法进行测试(这一点是通过测试这个属性的 type 是否是 function来实现的)。
  • 如果两个都为真,我们就会创建一个新的单击按钮,并应用 window.print() 作为单击事件处理器。
  • 最后一步就是将该按钮添加到该段落中去。

这一招对每个用户都有效,不管他们的应用环境如何。我们并没有向用户承诺提供一个可能无法使用的界面元素——我们只在该元素能正常工作的时候才将它显示出来。

什么时候该用什么

可能是我太理想主义了吧,但我实在不喜欢功能衰减这个概念。如果我创建了某些东西,但它在其它环境中只能勉强运行(或需要用户进行升级),我就对环境和用户的升级能力做了太多的假设。

在我的便携式计算机无法获得无线网络服务时,我用的是一款黑莓手机,当那些 Web 产品告知我它们需要启用 JavaScript 才能运行,而我应该开启我的 JavaScript 时,我郁闷透了。我无法开启 JavaScript ,但我肯定有资格作你们产品的用户——尤其是在我为了访问你们的服务花了许多钱在 GPRS 或 EDGE 网络上的时候!

然而,功能衰减在某些情况下也是切实可行的:

  • 在你想将一个旧产品翻新,而又没有时间、权限或能力来改变或替换它的情况下。
  • 如果你没有时间来完全完成一个渐进增强式的产品(通常是由于规划不良,或预算耗尽)的话。
  • 如果你的产品是特殊情况的话,比如说那些极高流量的网站,每毫秒的运行都意味着数以百万计的美元的波动。
  • 如果你的产品天然的非常依赖脚本,而使得维持“基础”版本比增强版本(地图,email 客户端程序,RSS 阅读程序)更有意义的话。

在其它所有情况下,渐进增强都能使终端用户和你自己更满意:

  • 不管产品的应用环境和浏览器能力如何,都需要产品可用。
  • 当一款新的浏览器推出或某个浏览器的扩展被广泛采用时,你就可以将你的产品功能提升至另一层次,而不用触及原始解决方案——功能衰减却可能会要求你修改原始解决方案。
  • 你还技术为其原本该有的样子——技术就是一种辅助措施而已,拥有该技术能更快地达成某个目标而已,而不是说“必须要有它”才能达到某个目标。
  • 如果你要添加新的功能,你可以在检查对这些功能的支持是否达到了某个水平之后,再予以实施,或者你可以将其添加到最初级的功能上,从而使你的网站在更高级的条件境下能表现得更好。无论如何,这种维护都是在原来的版本上进行的,而不是在两个不同的版本上。使一个渐进增强版的产品保持在最新状态,要比同时维护两个版本的工作量小得多。

总结

可以这么说,渐进增强和功能衰减都试图实现的同样的目标:使我们的产品对每个用户都可用。渐进增强要更好一些,同时在保证产品的可用性方面要更为稳定一些,但它需要花费更多的时间和精力。功能衰减使用更容易一些,可以作为已有产品的补丁来使用;它的后期维护要更难一些,但所需的初始工作量相比较少。

练习题

  • 本文所展示的打印链接示例既可以通过功能衰减的方法来实现,也可以通过渐进增强来实现。还有什么其它的例子也可以使用这两种方法,你能想到吗?
  • 假设你想用 JavaScript 来在提交某个表单之前,确保它的某个表单域中包含了一个 email 地址。你可以用什么不同的方法来实现?还有什么其它问题是应该考虑的?
  • 假设你想显示一幅地图,而且你想用渐进增强的方式来实现。你该从什么样的基础功能开始?
  • 假设你有一个由两个下拉列表控件构成的表单界面。在第一个控件中选择一个选项,就会改变第二个控件中供选择的选项。这种表单功能的备用方案是什么?会有什么问题?

联系我们

  • 网址:www.yercent.com
  • 电话:+86-531-66683968
  • 传真:+86-531-61365117
  • QQ:1251420996或564590102
  • Email: 该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。
当前位置:首页 建站知识 51. 平稳退化对渐进增强