现在的位置: 首页 > 综合 > 正文

打造可靠的 Ajax 应用程序: 第 1 部分:构建前端

2013年10月18日 ⁄ 综合 ⁄ 共 11527字 ⁄ 字号 评论关闭

2008 年 5 月 08 日

如今,Ajax 仍然是业界的热门字眼,越来越多的应用程序都采用 Ajax 技术构建。然而,构建一个好的 应用程序并不容易。本文将着重讨论如果构建直观易用的受 Ajax 驱动的应用程序。

Ajax 并不只是一种技术。大多数开发人员却认为它是,并试图借助诸如 XML 和 JavaScript 这类语言证明其观点。但这种观点非常局限,并且,忽视了付钱给您的人:客户,不管是咨询代理还是您的老板(只有您建立了令人满意的用户群,他们才能获得收入)。

客户并不关心技术;他们关心的是应用程序的外在表现如何,以及当他们通过鼠标和键盘操作时,应用程序如何响应。您可以将世界上所有的技术都构建到应用程序中,而此应用程序却不一定能有多成功,您也可以构建一个非常简单的 HTML应用程序,它却可以工作得很好。因此,我们的目标是要结合技术和可用性,这一点对 Ajax 应用程序而言尤其正确。

developerWorks Ajax 资源中心

请访问 Ajax 资源中心,这里几乎囊括了关于 Ajax 编程模型的所有信息,包括各种文章、教程、论坛、博客、wikis、活动和新闻。

Ajax 的承诺

了解 Ajax 所能提供的功能对于开发人员和用户而言都非常重要。不管您是否将应用程序定义为 Ajax,人们对 Web 应用程序都有了更高的期望,如果想要让客户满意,最好了解这些期望。

可用性

首先,Ajax 关乎可用性。有些开发人员可能会奇怪,因为 Ajax 已经给人们带来了瞬间的响应时间、小部件和可视工具以及各种各样的 GUI元素。这些绝对是 Ajax 体验的一部分,但是大多数用户 — 而非开发人员 — 只是发现 Ajax应用程序更好用。它们能像用户期望的那样响应,应用程序的元素 — 字段、按钮和图像 — 均符合用户的期望。

其结果就是应用程序很好使用。用户无需做很多查找,比如查找 zip 代码字段在哪以及又该如何在地图上做缩放。如果所设计的是 Ajax应用程序(并且即使设计的不是这类应用程序),就应该争取达到同等的可用性程度。用户试用和常识是最好的指导,接下来,我们将讨论一些可用来确保应用程序可用和直观的简单方法。

响应性

处理完可用性后,就需要处理 Ajax 应用程序的响应性了。初看上去,这似乎是有关速度的问题。Ajax应用程序无需在每次发生事件时都向服务器端程序提交并刷新页面,这意味着等待的减少(至少理论上如此)。然而,Ajax特性的这一部分多少有点人为因素。在 DSL 世界,等待并不是很多。您的母亲和祖母可能用的是有线modem,而不是拨号上网,如果您在工作中阅读本文,那么很可能所用的网络是 T1 或 T3。Ajax 应用程序的速度天生较快,这一点很难理解(如果速度真的较快,快多少?10 毫秒?100
毫秒?您知道这意味着多么短的时间么?)。

然而,Ajax 应用程序应该比传统应用程序有更好的响应性。这不仅仅是指速度这一个方面,它还涉及到了应用程序给人的感觉如何(而这主要体现在可用性和界面)。比如,假设您输入自己名字并开始选择您所喜欢的 Crocs 的颜色,在您进行其他操作的时候,程序会有很多时间执行其他任务。所以应用程序可能会获取您的地址、所保存的信用卡信息,可能还有您之前在访问这家网上商店时已经标示为朋友的那些人。所有这些信息可能会花费很多时间,但如果您正在忙着做其他一些事情,并且这些信息已经显示为可用,那么会觉得应用程序响应性
非常好。

需要一些技巧的是 — 我们将会对此详细加以讨论 — 何时开始制造 这种响应性。通过以特定的方式在应用程序中排列字段,就会知道用户将要遵循的操作流程。这样一来,我们就可以编写 Ajax 交互程序以便利用这一流程。请记住这一点,我们先对其稍做论述,稍后我们再用特定的示例回到这一主题。

是否需要桌面应用程序?

人们一直尝试使用 Ajax 将每个 Web 应用程序都转变为桌面应用程序。这听起来很棒,但在实践中并不能很好地工作。我曾使用过一个基于 Web的流行的 Web/个人生产力套件来模仿 Microsoft® Office。它能为约会安排给出弹出警示,这看起来很好。正如桌面应用程序Outlook 或 iCal 一样,对么?惟一的不同是它不是 一个桌面应用程序。它局限于浏览器。

最终结果如何呢?弹出提示似乎工作得很好 — 但前提是 Web 浏览器必须在屏幕的最前面。如果所使用的 Firefox 浏览器最小化或被挤到InDesign 或其他应用程序之后,将不能看到弹出提示。它没了。该套件是有问题的,它试图充当桌面应用程序却忘了其本质上是
Web 应用程序。所以不要犯同样的错误!

独特的类桌面界面

这是最能为人接受而同时又是最难的一个 Ajax 应用程序的特性。我们所说的 “感觉上” 像桌面应用程序,在很多时候,是指 “看起来”像桌面应用程序。我的公司使用的是 Zimbra 邮件套件,它模仿的是 MicrosoftOutlook,我猜想其中的原因一定是觉得看起来像桌面应用程序就会感觉上也像桌面应用程序。

有关这一问题,有很多不同的见解。有些人认为 Web 的目的就是要成为一种新的桌面。您将使用的是同样的应用程序 — 或其类似物—,只不过这些程序将都是在线的。初此之外,其余的看起来和感觉上均与之前无异。另一些人(我承认,我更偏向这一阵营)认为 Web是一种独特的空间,有些地方好于桌面应用程序,有些地方则更差。Web 是其自身的媒介,Web上的应用程序应该单独设计,而不能只简单克隆桌面应用程序。

不管何种情况,有一点很清楚,即 Ajax应用程序能够看起来比 1997 年的 HTML 表单要好很多,那时的表单只有大的灰色的 Submit Form 按钮和沉闷的“border=1” 装饰。所以 Ajax 范型需要更加丰富的体验,即使很多人在如何实现的问题上意见不尽相同。

一个示例应用程序

至此,我们已经讨论了太多的技术和理论上的东西。让我们现在深入一个示例应用程序,开始实践。为了立即开始,我选择使用 Nathan Smith 的 Hoverbox (有关链接,请参看

参考资料
部分)作为起点。Hoverbox 是一个简单的基于 CSS 的 Web 布局,让您可以在图片库的图像上移动并获得该图像的放大视图。图 1 显示了这个默认的 Hoverbox 演示:

图 1. 作为演示运行的 Hoverbox
Hoverbox 是一个简单的基于 CSS 的图片库查看器

对于这个示例,我们想要针对可用性的目的稍作修改,之后还会添加某些很酷的 Ajax 行为,以便当鼠标悬浮或单击此图像时,能得到更多有关此图像的信息。

更酷的 Lightbox

还有一种更酷的小部件,称为 Lightbox(也请参见
参考资料
部分)。我觉着这更有趣,而且看上去更好,但会涉及更多代码,所以为了展示的目的,我回避了它。您可以继续本文的阅读,然后再使用 Lightbox 实现这些想法。

调整 Hoverbox CSS

在开始使用 JavaScript 编写代码之前,让我们先来讨论一下我们的目标是什么。您将采用图片库的概念 — 使用 Hoverbox CSS—,并且除了弹出图像的放大视图之外,还会使用 Ajax 呈现一组有关图像的描述。所以需要做的第一件事情是提供页面上的一些空间以便添加注释。

请下载本文的示例文件并找到 hoverbox.css。该文件是图片库所需的 CSS。我们将对此文件进行一些重要更改,所以首先要修改该文件使其看起来类似
清单 1
(或者直接用清单 1 替代该文件内容):

清单 1. 针对图片库修改后的 CSS

                

*
{
	border: 0;
	margin: 0;
	padding: 0;
}

/* =Basic HTML, Non-essential
----------------------------------------------------------------------*/

a
{
	text-decoration: none;
}

body
{
	background: #fff;
	color: #777;
	padding: 50px;
}

#page {
  position: relative;
}

#images {
  float: left;
  width: 400px;
}

#details {
  color: #000;
}

h1
{
	background: inherit;
	border-bottom: 1px dashed #ccc;
	color: #933;
	font: 17px Georgia, serif;
	margin: 0 0 10px;
	padding: 0 0 5px;
	text-align: center;
}

p#footer
{
	clear: both;
	font: 10px Verdana, sans-serif;
	padding: 10px 0;
	text-align: center;
}

p a
{
	background: inherit;
	color: #777;
}

p a:hover
{
	background: inherit;
	color: #000;
}

/* =Hoverbox Code
----------------------------------------------------------------------*/

.hoverbox
{
        width: 375px;
	cursor: default;
	list-style: none;
}

.hoverbox a
{
	cursor: default;
}

.hoverbox a .preview
{
	display: none;
}

.hoverbox a:hover .preview
{
	display: block;
	position: absolute;
	top: -33px;
	left: -45px;
	z-index: 1;
}

.hoverbox img
{
	background: #fff;
	border-color: #aaa #ccc #ddd #bbb;
	border-style: solid;
	border-width: 1px;
	color: inherit;
	padding: 2px;
	vertical-align: top;
	width: 100px;
	height: 75px;
}

.hoverbox li
{
	background: #eee;
	border-color: #ddd #bbb #aaa #ccc;
	border-style: solid;
	border-width: 1px;
	color: inherit;
	display: inline;
	float: left;
	margin: 3px;
	padding: 5px;
	position: relative;
}

.hoverbox .preview
{
	border-color: #000;
	width: 200px;
	height: 150px;
}

/* Info details -----------------------------*/
.info-title {
  color: #933;
}

.info-date {
  font-size: 14px;
  color: #777;
}

.info-text {
  font: 10px Verdana, sans-serif;
  padding: 10px 0;
}

 

清单 1 添加了一些 div 元素,主要是为了能够将图片库作为一个单元处理,有关图像的细节(稍候会添加)则作为另一个主要因素。剩余的大部分更改均是修饰性的,是为了支持两栏的布局结构。

现在需要向 HTML 添加几个 div 元素,如清单 2 所示:

清单 2. 针对图片库修改后的 HTML

                

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Hoverbox Image Gallery<title>
<link rel="stylesheet" href='css/hoverbox.css' type="text/css" 
      media="screen, projection" />


</head>
<body>
<h1>Hoverbox Image Gallery</h1>


<div id="page">

<div id="images">
<ul class="hoverbox">
<li>
<img src="img/photo01.jpg" alt="description" /><img src="img/photo01.jpg" 
                 alt="description" class="preview" />
</li>
<li>
<img src="img/photo02.jpg" alt="description" /><img src="img/photo02.jpg" 
                 alt="description" class="preview" />
</li>
<li>
<img src="img/photo03.jpg" alt="description" /><img src="img/photo03.jpg" 
                 alt="description" class="preview" />
</li>
<li>
<img src="img/photo04.jpg" alt="description" /><img src="img/photo04.jpg" 
                 alt="description" class="preview" />
</li>
<li>
<img src="img/photo05.jpg" alt="description" /><img src="img/photo05.jpg" 
                 alt="description" class="preview" />
</li>
<li>
<img src="img/photo06.jpg" alt="description" /><img src="img/photo06.jpg" 
                 alt="description" class="preview" />
</li>
<li>
<img src="img/photo07.jpg" alt="description" /><img src="img/photo07.jpg" 
                 alt="description" class="preview" />
</li>
<li>
<img src="img/photo08.jpg" alt="description" /><img src="img/photo08.jpg" 
                 alt="description" class="preview" />
</li>
<li>
<img src="img/photo09.jpg" alt="description" /><img src="img/photo09.jpg" 
                 alt="description" class="preview" />
</li>
<li>
<img src="img/photo10.jpg" alt="description" /><img src="img/photo10.jpg" 
                 alt="description" class="preview" />
</li>
<li>
<img src="img/photo11.jpg" alt="description" /><img src="img/photo11.jpg" 
                 alt="description" class="preview" />
</li>
<li>
<img src="img/photo12.jpg" alt="description" /><img src="img/photo12.jpg" 
                 alt="description" class="preview" />
</li>
<li>
<img src="img/photo13.jpg" alt="description" /><img src="img/photo13.jpg" 
                 alt="description" class="preview" />
</li>
<li>
<img src="img/photo14.jpg" alt="description" /><img src="img/photo14.jpg" 
                 alt="description" class="preview" />
</li>
<li>
<img src="img/photo15.jpg" alt="description" /><img src="img/photo15.jpg" 
                 alt="description" class="preview" />
</li>
<li>
<img src="img/photo16.jpg" alt="description" /><img src="img/photo16.jpg" 
                 alt="description" class="preview" />
</li>
<li>
<img src="img/photo17.jpg" alt="description" /><img src="img/photo17.jpg" 
                 alt="description" class="preview" />
</li>
<li>
<img src="img/photo18.jpg" alt="description" /><img src="img/photo18.jpg" 
                 alt="description" class="preview" />
</li>
<li>
<img src="img/photo19.jpg" alt="description" /><img src="img/photo19.jpg" 
                 alt="description" class="preview" />
</li>
<li>
<img src="img/photo20.jpg" alt="description" /><img src="img/photo20.jpg" 
                 alt="description" class="preview" />
</li>
</ul>
</div>

<p id="footer"> <a href="http://validator.w3.org/check/referer">XHTML</a> 
<a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a> 
<a href="http://www.contentquality.com/mynewtester/cynthia.exe?
Url1=http://host.sonspring.com/hoverbox/">508</a>
 | Hoverbox by <a href="http://sonspring.com/">Nathan Smith</a>. | 
Read the <a href="http://sonspring.com/journal/hoverbox-image-gallery">Tutorial</a>
.</p>
</div>

</body>
</html>

 

保存和加载页面,它应该如图 2 所示:

图 2. 修改后的 Hoverbox 演示
我们已经在右侧为图像细节留出了空间

注意: 此 CSS 的某些地方有些繁乱。我没有花太多时间对它进行调整,相反,我努力进行了最为直接的更改以便它能清楚展示我的意图。如果您有兴趣对其进行简化和修整,不妨一试!

 



回页首

用户界面 101: 从左向右阅读

虽然可能没有注意到,但您已经在这个更改过程中做出了一项重要决定:您已经决定将图片库置于页面的左侧,把对每个图片的解释置于页面的右侧。您有如下几个选择:

  • 将图片库置于左侧,将有关图片的信息置于右侧(正如您所做的那样)。
  • 将图片库置于右侧,将有关图片的信息置于左侧(与您所做的相反)。
  • 提出非上面这两种排列方式的新奇排列方式。

最为明显的禁忌是第二种选择,其中的原因是:西方人习惯于从左向右阅读(参见
图 3
)。这是我们从小就养成的一种习惯,从小,父母或祖父母就是这样用手指点着书上的文字教我们念书的。我们的眼睛已经习惯于从左向右移动(这里有一个较大的理论,称为 z字型跟踪,而这超出了本文的讨论范围)。任何时候,只要违背了这一习惯,那就意味着您想要跟人类数十年的习惯做法对抗。在图片库中,看到左侧的一个图片,就可以单击或将鼠标悬停于其上,然后再着眼阅读有关此图像的信息。这是一种非常 自然的过程,用户会感觉很舒服,即便他们对 Internet 了解不深。

图 3. 一种标准的 Z 字型跟踪模式,由左向右再向下
人类大脑习惯于从左向右

如果翻转这个范型,就会创建一种很不自然的从右向左的形式(参见
图 4
)。图片在右侧,需要向左 看以便阅读有关此图片的信息。是大问题么?表面上看似乎不是,而且用户也不会告诉您说:“哇,我讨厌从右向左查看。”然而,研究表明,这种不自然的方式会产生细微的不适感觉。所以最好是遵照书籍的编排方式。

图 4. 强迫眼从右向左移动
西方人不习惯从右向左阅读

第三个选择 — 提出新奇的编排方式,比如在图片库下方弹出信息或是将图片像洗牌似地摊开并在图片库中间插入有关图片的信息 —这是很危险的。对于熟悉计算机和下一代应用程序的用户而言,问题可能不大。但对经验不丰富的用户(尤其是对于那些刚刚知道如何登录查看图片和进行电子支付的人),这种新奇反而会让他们觉得讨厌和困惑。不怎么有经验的用户不希望 所看到的东西四处移动、不停闪动或以出乎其意料的方式展现。他们更希望在线体验能够尽量简单和直观,就像阅读一本书或一份报纸一样!所以在设计自己的用户界面时,请务必遵循从左到右的方式;这一定会有所回报的。

 



回页首

模拟数据

到达这个阶段,大多数开发人员都会立即转入实现 JavaScript 事件处理器。请稍等片刻。我们需要先来看看页面上的其他数据是何模样。

“嵌入” HTML 让人头痛

在这个阶段之所以进行一些实验性工作的最重要的原因是处理 HTML — 即使在最好的情况下 — 让人头痛。它多变,而且还会充满标记符号。还好,我们已经学会了适应这些。不过,将这样的 HTML 嵌入 JavaScript 和 DOM,将更容易把
p 元素或 id 属性放错地方。通过模拟数据,就能确保它能如预期的那样显示,而且没有这些麻烦。

确保了数据能正确显示之后,就可很容易将其用于任何需要的代码中了。将数据剥离开来并只侧重于结构也很简单,并且这也是处理 DOM 所需做的。

开始大,随后变小

让我们向页面添加一点 HTML,为每个图片模拟标题、日期和一个日志式的条目。在页脚之前,图片 div 后添加 “细节”
div

清单 3. 页面的 HTML

                

<a href="#"><img src="img/photo20.jpg" alt="description" />
<img src="img/photo20.jpg" alt="description" class="preview" /></a>
</li>
</ul>
</div>

<div id="details">
<h2 class="info-title">Sunrise over the bay</h2>
<h3 class="info-date">27 October, 2006</h3>
<p class="info-text">Here is what I experienced when 
I took this photo.</p>
</div>

<p id="footer"><a href="http://validator.w3.org/check/referer">XHTML</a> 
<a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a>
<a href="http://www.contentquality.com/mynewtester/cynthia.exe?Url1=
http://host.sonspring.com/hoverbox/">508</a> | 
Hoverbox by <a href="http://sonspring.com/">Nathan Smith</a>. | 
Read the 
<a href="http://sonspring.com/journal/hoverbox-image-gallery">Tutorial</a>.</p>
</div>

</body>

 

这些类的 CSS 在
清单 1
中。在浏览器内装载此页面并确保它正确显示(参见
图 5
):

图 5. 每个图片一个条目
当将鼠标置于图片之上时,就会得到关于此图片的信息

这看似简单,但实际上其中却发生了一些重要事情。首先也是最为重要的一点是文本随着其在页面中向下的移动而变得更小了。虽然这看上去像个小细节,但对从左向右编排的 Web 页感觉却影响极大(还记得在本文开始部分对可用性的讨论么?)。图 6 给出了文本在页面向下移动的理想过程:

图 6. 文本应该随着其在页面向下的移动而变小
标题开始大,随后变小

这一点可能看起来无足轻重,但它却能强烈影响着用户对应用程序的理解。实际上,让我们将居于整个页面顶部的图片库变大一些,看看这对页面有何影响。更改
h1
的 CSS:

h1
{
	background: inherit;
	border-bottom: 1px dashed #ccc;
	color: #933;
	font: 32px Georgia, serif;
        font-weight: bold;
	margin: 0 0 10px;
	padding: 0 0 5px;
	text-align: center;
}

 

这是一个很小的改变,但如果仔细察看
图 7
,页面看上去很不一样:

图 7. 增加页面标题的字体大小
现在文本从大到小一致地变化

保持一致性!

页面现在存在的最大问题是缺少字体的一致性。标题是 Georgia 字体,而图片细节、标题和日期则不是。外观很乱,所以要进行几个细微更改来解决这个问题,对接近底部的 CSS 也要做更改:

/* Info details -----------------------------*/
.info-title {
  font: Georgia;
  color: #933;
}

.info-date {
  font: 14px Georgia;
  color: #777;
}

.info-text {
  font: 10px Verdana, sans-serif;
  padding: 10px 0;
}

 

我们已经将字体更改为 Georgia 以便与标题字体一致(是的,CSS 提供了更通用的方式,但我还是一如既往地选择了最为明显的方式)。

除主体文本之外

您可能已经注意到了主体文本 — 有关图片的文本部分 — 与页面的其余部分 一致。这是因为主体文本打破了一致性原则,尤其是当标题字体是 serif 字体的时候(serif 字体有一些花体,比如字母 “y” 的最后一笔的末尾)。

Serif 字体虽然很棒但如果是大块文本会造成眼睛疲劳。很多书籍都采用了 sans-serif 字体印刷(尽管作为一种 serif 字体的 Times New Roman 字体很流行)。实际上,如果想要向出版社投稿,出版社都会要求 提交稿件的字体为 sans-serif。所以不管是短还是长的文本,都请使用 sans-serif 字体。进行了所有这些字体更改之后的结果如图 8 所示:

图 8. 当前的图片库
除了图片细节的字体为 sans-serif 之外,其余字体一致

一点空间……

引起我注意的最后一件事情是顶部的标题较图片和图片细节看起来是多么地狭促。这很容易修复,只需稍微增加页面标题和图片间的间距即可:

h1
{
	background: inherit;
	border-bottom: 1px dashed #ccc;
	color: #933;
	font: 32px Georgia, serif;
        font-weight: bold;
	margin: 0 0 20px;
	padding: 0 0 15px;
	text-align: center;
}

 

此结果如
图 9
所示:

图 9. 向顶部添加一点空间
现在,页面标题和图片库以及图片细节间的空间更多了

这些微小更改看上去可能有些愚蠢,甚至不合逻辑。但您必须记住我在本文开始的部分所讨论的:应用程序是为实际的用户 而构建的,而绝非只是为了炫耀您的技能。所以调整字体、确保一致性以及间距合适等等,这些都会使应用程序更加专业、可用性更好。

 



回页首

Ajax 在哪?

分享本篇文章……

 

digg 提交到 Digg
del.icio.us 发布到 del.icio.us
Slashdot Slashdot 一下!

我猜想有些读者都在急切地寻找 Ajax 代码:XMLHttpRequest 对象和 send() 调用。不用急,本系列的下一篇文章会涉及这部分内容。本文的重点是打造可用的前端设置,而这所涉及的是 JavaScript 之外的很多内容。实际上,它更多涉及的是字体、观感和空间。

尽管这看上去有些乏味(如果您是一位分析型的人就更是如此了),但您还是必须 要处理美学方面的这些问题。否则,所得到的应用程序技术上将会是一流的,但外观会极丑且不可用。相信我,Internet 上不乏这样的应用程序。

所以请在上述问题上花些时间。重点放在从左向右的编排方式、保持字体一致以及让字体由大变小,此外也需在间距设置和保持整齐的外观上下些功夫。用户会因此而喜爱您,您也就准备好可以面对下一篇文章(会涉及到很多编程)的挑战了。

抱歉!评论已关闭.