这是一篇译文,其中涉及了不少比较专业的概念,我将用一系列文章来介绍这些概念,这些文章对于网页设计进行了更加深入的探讨,也许在我们看来有些学究气了,但是通过这种探讨,我们从中应该看到一些好的方法论和更多的用户体验关怀。
Progressive Enhancement(逐步增强)开发模式正逐步成为基于标准设计的最佳实践。从简洁,语义化的HTML标记开始,通过Javascript和CSS层层渐进式增强,我们试图为任何受众创建可用的体验,对于那些功能不那么强大的设备和浏览器能获得一个相对简单但是功能完整的用户体验,而其他那些功能齐备的则将获得剩下的附加特性和体验。
这是就是PE(Progressive Enhancement 以下缩写为PE)的基本理论。但是在实践过程中,这些增强仍然被推送给了绝大多数设备,其中包括大量不支持这些特性的对象,比如较低版本的浏览器或者是功能受限的移动客户端。这些设备一开始的确获得简单但功能完整的页面,但随后被“增强”到了乱糟糟的页面。这显然是和PE理论背道而驰的。
那我们应该怎么做增强以确保所有的设备和浏览器获得正确的效果呢?测试,这时候我们需要的是通过逐级测试来确保这点。
兼容性测试
不久之前,我们发现可以使用很简单的Javascript代码来测试目标设备对于CSS的支持情况。让我们从一个很简单的盒模型测试开始,我们插入一个对象到当前Document中,然后设置一些样式属性,然后通过Javascript来校验是否被正确支持了。
function boxmodel(){
var newDiv = document.createElement('div');
document.body.appendChild(newDiv);
newDiv.style.width = '20px';
newDiv.style.padding = '10px';
var divWidth = newDiv.offsetWidth;
document.body.removeChild(newDiv);
return divWidth == 40;
}
通过上面的TestCase,我们能很快的检查目标设备是否正确支持盒模型,然后我们也能采取对应的增强方式。
有了上面的这个主意,我们能类似的写出如下测试用例:
float
clear
position
overflow
line-height
当然仅通过CSS测试并不能覆盖到所有情况,幸运的是,我们还能通过Javascript测试来做其他兼容性测试。(译注,这可能是大家比较熟悉的浏览器检测了)。
document.createElement()
document.getElementById()
xmlHttpRequest()
window.onresize()
window.print()
通过上述测试,我们可以知道是否可以正确显示客户的应用。
我和我在Filament Group的同事开发了testUserDevice.js,来完整上述所有的测试。
利用这些测试结果
整合testUserDevice.js到一个页面上是相当简单的,讲JS文件包含进来,然后调用testUserDevice.init()方法就可以了。
为了更好的阐述这些概念,我们来看一个具体的例子,这是一个有一定复杂度的表单页面,让我们从最基本的HTML开始。
DEMO1
=== CSS增强
当目标设备通过了我们的测试代码,会对页面进行一系列的增强,默认情况下,会进行下列DOM更新:
- 样式Class
enhanced 被加到[BODY]元素上。
- (
title="enhanced") 可选的样式表文件被启用。
- (
title="not_enhanced") 与之相反的,所有这些非增强样式表文件被禁用。
这样的变化给你提供好几个契机去做层进式的增强,比如BODY标记上的样式增强。来看下例子:
body div.example {
margin: 1em 0;
}
如果用户的浏览器通过了测试,我们可以使用float布局来实现水平排列。
body.enhanced div.example {
float: left;
width: 30%;
margin: 0;
}
来看一下示意图,

这只是一个很小的变化,当你要做一些比较复杂的增强的时候,使用选择器来实现就显得不怎么合适了,所以这个时候,你应该使用可选的样式表文件来替换原来的效果。
这虽然只是简单的样式表文件替换法,但重要的地方在于我们的增强只在能够正确解释的地方被应用了。让我们再来看一下前面的Demo页面,看看现在的增强后的效果。
Demo 2
尽管我们做的只是很简单的CSS增强,但是测试目标设备是否能够正确支持依然是十分有必要性的。(译注:术抑或是道,以何治天下)
Javascript增强
很多页面增强使用了Javascript。testUserDevice.js 允许你具体指定一些script来做增强。非常简单,你只需要将你的增强方法作为参数传给我们的方法就可以了。
testUserDevice.init( function(){
/* »fancy stuff goes here */
} );
就像你看到的这样,我们将一个匿名方法传给了init方法。如果测试通过,这个方法就会被调用执行。记住一点,这些动作有可能在DOM树构建完毕前触发,所以DOM相关的方法仍然应该放在DOM树构建完毕之后,比如jQuery的ready事件或者是body.onload事件之后。
来看一下我们的最终Demo页面,有了如下增强
生日输入框有了日历供选择日期。
有了滑块选项。
宠物那栏也是根据用户输入,动态展示一下输入框。
有了自动完成功能。
使用了Ajax提交方式。
Demo 3
一次测试,终身受用
在完成测试之后,testUserDevice.js 会留下一个cookie记录这次的测试结果,这样也能带来性能上的好处。我们通过PHP代码也能非常方便的去处理这些增强动作:
<?php
//check for cookie (enhanced=pass), and set the »
//stylesheet rel depending on its value
$cssRel = ($_COOKIE['enhanced'] == "pass") ? »
"stylesheet" : "alternate stylesheet";
echo '<link rel="' . $cssRel . '" »
type="text/css" href="css/enhanced.css" mce_href="css/enhanced.css" »
title="enhanced" />';
?>
同样的,testUserDevice.js 支持你加入更多的自定义测试。下面就为大家介绍下,如何编写自定义的测试用例,并且加入到testUserDevice.js 中去。
(译注:此处并未全文译出,我想程序员间的交流代码足够了,代码是无国界的,说多了也没什么用处。)
1
testUserDevice.init([
{ testName: 'ajaxCapable',
pass: ['ajax'],
scripting: function(){ useAjax(); }
}
]);
2
testUserDevice.add( 'confirm', function(){
if(window.confirm){return true;}
else {return false;}
});
3
testUserDevice.add( 'confirm', function(){
return (window.confirm) ? true : false;});
原文地址:http://alistapart.com/articles/testdriven
Reprinted with the permission of A List Apart and the author[s]
//====================================================
译者:
这里说的测试驱动,并不是我们平日里程序开发中的测试驱动。当然两者的理念其实某种角度上来说是一样的,只做确信正确的改动。我平日里工作中,说实话没有过这样的思考。如何适应各种不同的目标客户端,我想到的第一个是尽可能的去兼容,但是PE这种理念从另一个角度提出解决方案。给不同的人不同的,但必须是完整且正确的体验。这点值得我们进行更深一步的讨论。
Filed under: 光明神 - 译林, 绾青丝 - WebDesign, css, progressive_enhancement, 测试驱动, 网页设计 |