频 道 直 达 - 新闻 - 培训 - 软件 - 教程 - 前沿 - 组网 - 系统应用 - 安全 - 编程 - 存储 - 操作系统 - 数据库 - 服务器 - 专题 - 产品 - 案例库 - 读书 - 博客 - BBS
51CTO.COM_中国最大的网络技术网站
找资料:

2.4 分解电子书阅读器程序

作者: Michael Morrison著/李松风译 出处:机械工业出版社  2008-04-21 11:56    砖    好    评论   进入论坛
阅读提示:《Ajax构建工具箱指南》第2章主要讲述了深入Ajax应用程序,本节分解电子书阅读器程序。

2.4   分解电子书阅读器程序

现在该终止空谈Ajax理论,开始讨论一些实际的问题了。本章剩余的内容将探索在图2-2和图2-3中所看到的Booker电子书阅读器的内部构成,同时解释其工作原理。你可以把这一节的内容想像成即将开始学习的本书后面每一章内容的迷你版,以后各章将分别剖析真实的Ajax应用示例,以便根据你的需要轻松地加以重用。虽然我不能保证在没有JavaScript经验的情况下,你可以完全理解每一行代码,但是我会明确地为你指出一些相关的位置,你可以在这些位置上对代码进行训练有素的修改,从而通过自定义的代码满足自己的需要。换句话说,我不会教你怎样做一个机械师,而是要告诉你应该用你的扳手拧什么地方。

在本章前面,我解释了每个Ajax应用最终都将归结为两部分—客户端(浏览器)的JavaScript程序和负责响应Ajax请求的服务器端程序。虽然服务器端程序可以通过很多种语言编写,但本书中多数示例都将采用PHP。PHP是一门足够简单的语言,但并非一定要会使用PHP才能理解示例代码并进行自定义的修改。

这个Booker示例有点独特,它不需要在服务器端进行任何自定义的开发。因为所有Ajax请求都要从Web服务器上下载完整的电子书文本,所以服务器本身就足够了。如果该应用需要摘录图书中的一部分内容(比如个别的章)那么你就需要在服务器上开发一个自定义的程序。

当然,在客户端还是需要进行自定义的编程工作。也就是说,客户端的程序必须对用户从选择列表中选择电子图书的动作给予响应。此时自定义的代码必须异步地从服务器加载电子书并将其显示到页面中。从很多方面来说,这都是一个Ajax请求中最基本的形式,因为你不需要向服务器传递任何信息,而只需要在生成Ajax请求时指定电子书所在文本文件的名称。这些内容稍后再详细介绍,我们先来看看这些电子书。

电子书

在Booker示例中,电子书是以纯文本文件的形式提供的,每个文件的扩展名都是熟悉的.txt。你可以像打开并编辑其他文本文件一样使用Vi、Emacs或Pico(Linux系统),记事本(Windows系统)或者TextEdit(Mac系统)来打开并编辑这些文件。下面列出了包含在示例应用程序中的图书及相关的文本文件:

Alice's Adventures in Wonderland—book_alicewonderland.txt
Frankenstein—book_frankenstein.txt
Moby Dick—book_mobydick.txt
War and Peace—book_warandpeace.txt
The War of the Worlds—book_warofworlds.txt
你可能已经注意到了,电子书文件的名称都有非常清楚的模式,即它们的格式都是book_AbbrevTitle.txt,其中AbbrevTitle是简略的书名。在遵循这种电子书文件名标准格式的基础上,很容易以程序化的方式响应用户在页面选择列表中所作出的选择动作。更具体地说,可以使用下面的表达式来构建一个文件名:
"book_" + AbbrevTitle + ".txt"

稍后你会看到,事实上这正是为响应选项变化而处理要加载电子书的代码的实际工作方式。

Booker示例中的页面

Booker示例应用程序中所有重量级的内容都位于booker.html这个网页文件中,这个文件中包含HTML和JavaScript代码以及一些CSS样式。在介绍这些代码之前,我们再来看一看这个应用程序在实际中的效果,如图2-4所示,这一次加载的是电子书Frankenstein。

虽然JavaScript代码在HTML文档中的位置更靠前,但先看一看主体中的HTML代码更有意义:

<body style="background:#EEEEEE"
onload="document.getElementById('book').selectedIndex = 0;
loadBook(document.getElementById('book').options[
document.getElementById('book').selectedIndex].value)">
<div id="ajaxState" style="display:block"></div>
<br />
<div style="margin-left:10%">Select book:
<select id="book" onchange=
"loadBook(this.options[this.selectedIndex].value)">
<option value="alicewonderland">Alice's Adventure's in
Wonderland by Lewis Carroll</option>
<option value="frankenstein">Frankenstein by Mary
Shelley</option>
<option value="mobydick">Moby Dick by Herman
Melville</option>
<option value="warandpeace">War and Peace by Leo
Tolstoy</option>
<option value="warofworlds">The War of the Worlds by H.G.
Wells</option>
</select>
</div>
<br />
<div id="booktext" style="margin-left:10%; margin-right:10%;
padding:2%; background:#FFFFFF; border:thin solid #333333">
</div>
</body>

其中大部分代码都用于构建电子书选择列表,也就是<select>标签之间的部分。而且,每本电子书对应的<option>标签的value属性值都是相应图书的简略书名。JavaScript代码正是利用选项的这个属性值(alicewonderland)来组合成电子书文本文件的名称(book_alicewonderland.txt)。

从页面中向下移动一点,你会看到一个ID值为booktext的div元素。这个div元素就是在通过Ajax请求加载完一本电子书后,保存其文本内容的元素。换句话说,这个div元素是页面中的主显示区域。其中的CSS样式是为了让它在页面中居中,让文本与边界保持一些距离,同时还给它加上了一个可见的边框。当通过一个Ajax请求加载完一本电子书之后,页面中的JavaScript代码就会通过这个div的ID属性值将其内容设置成电子书的文本。
现在来看一下选择列表代码的第二行,这大概是整个页面中最关键的一行代码了。这行代码用于定义选择列表的onchange事件处理程序,其中的JavaScript代码如下:

loadBook(this.options[this.selectedIndex].value) 
这就是基于选择列表中项目的变化而加载电子书的代码。这行代码将当前选中的电子书选项的值传递给了自定义的loadBook()函数。下面是这个函数的代码:
function loadBook(title) {
replaceText(document.getElementById("booktext"), "Loading...");
ajaxSendRequest("GET", "book_" + title + ".txt", handleRequest);
}

啊哈,是两个熟悉的函数!如果你回忆一下前面关于Ajax工具箱的讨论,一定记得我们曾解释过replaceText()和ajaxSendRequest()这两个函数。回想一下,replaceText()函数用于设置任意HTML元素的内容。在这里,用它把主div元素(booktext)的文本设置为“Loading...”,以便用户知道当前正在加载电子书。当前的Ajax请求则通过ajaxSendRequest()函数进行初始化,其中使用了GET请求方法。ajaxSendRequest()函数的第二个参数是要加载电子书的文件名,文件名的格式为book_AbbrevTitle.txt。而最后一个参数是当Ajax请求完成(例如电子书加载完成)时调用的自定义处理函数。

好吧,如果前面这一段怎么听都像是一种技术上的表述,那我实在抱歉。并不希望你对我所描述的任何一个细节都紧抓不放。随着学习的Ajax应用不断增多,你就会慢慢觉得这些描述越来越自然和熟悉。在此期间,只需要理解代码中最关键的点,以便根据自己的需求进行自定义。这个关键的点我们将在下一节介绍。
在对Booker应用程序蜻蜓点水般浏览的过程中,值得重视的另一个关键函数就是handleRequest(),它是一个自定义函数,当一个Ajax请求完成时被调用。其代码如下:

function handleRequest() {
if (request.readyState == 4 && request.status == 200) {
replaceText(document.getElementById("booktext"),
request.responseText);
}
ajaxUpdateState();
}

希望这些代码不会像你想像的那么难以理解。函数中的第一行代码通过检测确保请求完全成功。其中,涉及到检查request对象的readyState和status这两个属性的值。这是一行非常标准的Ajax代码,这行代码会原封不动地出现在任何Ajax应用程序中。这两个被检查的属性值与标准的XMLHttpRequest对象直接相关,附录 B详细介绍了XMLHttpRequest对象。你可以抽时间学习一下附录 B中的内容,以便加深对Ajax工具箱背后工作原理的理解。但现在,只要知道if语句是通过检查,来确保请求已经完成,并且没有任何问题就足够了。

在if语句中,通过调用replaceText()函数将页面中主div元素(booktext)的内容设置为刚刚加载的电子书文本。其中关键在于使用了request对象的responseText属性,该属性中保存着基于请求响应的数据。在后面你会看到,当我们处理一个Ajax请求的结果时,对于纯文本数据要使用responseText属性,而对于XML数据则要使用responseXML属性。

handleRequest()函数中的最后一行代码调用了ajaxUpdateStatus()函数,这个函数负责更新页面顶部的Ajax诊断栏。把对这个函数的调用放在if语句外部是非常重要的,因为只有这样才能保证每次XMLHttpRequest对象的状态发生变化时都会调用这个函数。这里还需要说明的是,ajaxUpdateState()函数在执行时,需要在页面中提前放置一个特殊的div元素。如果你回过头来再看一下Booker应用程序中那个页面的HTML代码,会发现一个由下面代码定义的div元素:

 <div id="ajaxState" style="display:block"></div>  
ajaxUpdateStatus()函数会查找一个ID值为ajaxState的div元素,然后对这个div元素的背景颜色和内容进行相应的设置。如果你想要隐藏Ajax诊断栏,只需把这个div元素的style属性值修改为display:none即可。如果以后需要再显示它,那么把这个style属性的值改回display:block就行了。当你完成了一个Ajax应用的开发并打算完全去掉这个诊断栏时,只需完全删除这个div元素,同时也删除调用ajaxUpdateStatus()的那行代码即可。
另外,还需要解释的一点内部操作是body元素的onload事件处理程序,这个处理程序是非常重要的。因为,它决定了哪本电子书在初始时处于被选中的状态,同时也保证了加载适当的图书内容。下面就是在onload事件处理程序中设定的代码:
document.getElementById('book').selectedIndex = 0;
loadBook(document.getElementById('book').options[
document.getElementById('book').selectedIndex].value);

第一行代码将选择列表中的第一个项目(项目0)设置为了被选中的项目。因为选择列表的索引是从0开始计数的,所以要用0来表示第一个列表项目。如果想在一开始选择第二个项目,那么就要将selectedIndex属性设置为1

第二和第三行代码其实是一行,因为太长了所以才分成两行。这行代码看起来比较乱,是因为需要使用两次getElementById()函数来取得选择列表对象。如果把这个getElementById()函数替换成一个简短的名字,这行代码会变得更容易理解。下面就是把选择列表对象重新命名为rel之后的代码简化版:

 sel.selectedIndex = 0;
loadBook(sel.options[sel.selectedIndex].value);

现在,但愿你能看出来给loadBook()传递的参数是当前选中的电子书的值。或者更具体一点说,它传递的是当前选中的电子书的简略书名。回忆一下前面讨论过的内容,loadBook()函数要使用这个简略书名来构造一个电子书的标准文件名,然后再把这个文件名作为一个参数传递给Ajax请求。
【责任编辑:夏书 TEL:(010)68476606】

回书目   上一节   下一节
专题
程序员如何成长?
解析Ajax开发框架 走进Ajax开发应用
Ajax明天会HOT还是OVER?
微软的Ajax:Atlas(ASP.net AJAX)
AJAX 51CTO技术座谈会
我也说两句

匿名发表

(如果看不清请点击图片进行更换)


中 国 最 大 的 网 络 技 术 网 站 ·
技 术 成 就 梦 想
订阅技术快讯
电子杂志下载
名称:SQL Server数据库管理精品黄皮书
简介:书中文章经过精挑细选,便于用户能根据自己的实际工作和学习,快速在本书寻找到相关资料。内容涵盖了SQL Server的安装与升级、语句查询、数据备份和恢复、自动化任务、数据同步、数据字典、安全和预防、性能和优化、集群等各方面应用信息,以及DBA管理人员在数据库管理工作中
名称:2007路由技术大全
简介:《2007路由技术大全》由51CTO.com网站特别策划制作,该书包括路由器技术、路由器产品、路由器配置、安全设置、路由器故障处理、路由器密码恢复,以及广大网友在实践使用中的心得经验和技巧文章,内容注重实用性,适用于初学者入门,也适合多年从业者提高,是一本实践和理论完
名称:网络安全精品应用黄皮书
简介:《2007精品网络安全黄皮书》包括了9个大类24个小类, 800余篇文章,内容包含了熊猫烧香病毒、DDOS攻击、ARP病等热点问题的介绍及解决方案。从病毒查杀、防范、系统、数据等各方面的安全设置到黑客技术的了解、防范,涉及到了安全应用的全部领域, 由浅至深内容全面。
见证中国网络安全二十年
见证中国网络安全二十年
勇闯IT培训黑色围城
勇闯IT培训黑色围城
技术人求职简历完备手册
技术人求职简历完备手册
· 技术人求职简历完备手册
· 华为员工自杀频频拷问..
· 视频访谈:网管员如何踏..
· 首届中国IT工程师生态..
· 思科全球CEO钱伯斯第七..
· 北漂技术人90天求职纪实
· 2007年互联网大会
· 龙芯要做中国的“奔腾”
· IPv6协议--拓展网络无..
· 国际文档格式标准开战
· 微软出价446亿美元收购..
· 贝恩资本携手华为22亿..
· Linux——从菜鸟到高手
· SOA 面向服务架构
· 2008年4月全国计算机等..
· 微软Forefront企业安全..
ARP攻击防范与解决方案
ARP攻击防范与解决方案
iSCSI应用与发展
iSCSI应用与发展
SQL Server 2008/2005全解
SQL Server 2008/2005全解
· SQL Server 2008/2005..
· SOA 面向服务架构
· SQL Server 2008/2005..
· iSCSI应用与发展
· RAID——磁盘阵列基础
· 中间件应用技术专题
· SQL Server入门到精通
· 病毒查杀专题
· 国际文档格式标准开战
· 路由器设置与口令恢复
· Linux防火墙
· 打造安全服务器
· SOA 面向服务架构
· PHP开发应用手册
· ADSL应用面面俱到
· 入侵防护系统(IPS)初探
ARP攻击防范与解决方案
ARP攻击防范与解决方案
SQL Server 2008/2005全解
SQL Server 2008/2005全解
iSCSI应用与发展
iSCSI应用与发展
· iSCSI应用与发展
· 中间件应用技术专题
· SQL Server入门到精通
· SQL Server 2008/2005..
· SOA 面向服务架构
· iSCSI应用与发展
· RAID——磁盘阵列基础
· 病毒查杀专题
· 路由器设置与口令恢复
· SOA 面向服务架构
· 了解统一威胁管理(UTM)..
· ADSL应用面面俱到
· ADSL应用面面俱到
· 反垃圾邮件技术应用
· PHP开发应用手册
· 中间件应用技术专题