7.2 jQuery表单插件—Form

7.2.1 Form插件简介

jQuery Form插件是一个优秀的Ajax表单插件,可以非常容易地、无侵入地升级HTML表单以支持Ajax。jQuery Form有两个核心方法—ajaxForm()和ajaxSubmit(),它们集合了从控制表单元素到决定如何管理提交进程的功能。另外,插件还包括其他的一些方法:formToArray()、formSerialize()、fieldSerialize()、fieldValue()、clearForm()、clearFields()和resetForm()等。

Mike Alsup设计了jQuery Form插件,并进行改善和维护。

7.2.2 下载地址

jQuery Form表单插件的下载地址为:

http://jquery.malsup.com/form/#download

在图7-9所示的界面中,读者可以下载该插件,并在该网站上查看简单上手说明、API、实例代码。文件上传说明和FAQ等。

[插图]

图7-9 jQuery Form表单插件官方网站截图

7.2.3 快速上手

在HTML页面上添加一个form表单,然后引入jQuery库和Form插件,并编写Ajax提交jQuery代码如下:

[插图]

当表单被提交时,“姓名”、“地址”和“自我介绍”字段的值会以无刷新的方式提交到文件demo.php中。如果服务器返回一个成功状态,那么用户将会看到“提交成功!欢迎下次再来!”的提示。

7.2.4 核心方法—ajaxForm()和ajaxSubmit()

正如上例的代码所示,通过核心方法ajaxForm(),能很容易地将表单升级为Ajax提交方式。

[插图]

Form插件还有一个核心方法ajaxSubmit(),也能完成同样的功能,代码如下:

[插图]

通过调用 ajaxSubmit()方法来响应用户的提交表单操作,从而使表单的提交方式由传统的提交方式转变为Ajax提交方式。

通过Form插件的这两个核心方法,都可以在不修改表单的HTML代码结构的情况下,轻易地将表单的提交方式升级为Ajax提交方式。

7.2.5 ajaxForm()方法和ajaxSubmit()方法的参数

ajaxForm()方法和ajaxSubmit()方法都能接受0个或者1个参数。当为单个的参数时,该参数既可以是一个回调函数,也可以是一个 options 对象。上面例子的参数就是回调函数。接下来介绍options对象,通过给ajaxForm()方法和ajaxSubmit()方法传递options对象,使得它们对表单拥有更多的控制权。

首先定义一个对象options,然后在对象里设置参数,代码如下:

[插图]

定义options对象之后,就可以把这个options对象传递给ajaxForm()方法,jQuery代码如下:

[插图]

或者传递给ajaxSubmit()方法,jQuery代码如下:

[插图]

在 options 对象里,指定了两个回调函数,即 beforeSubmit:showRequest和success: show Response,它们分别会在表单提交前和表单提交后被调用。

下面来看看这两个回调函数具体有哪些参数。

  • beforeSubmit—提交前的回调函数

提交前的回调函数的代码如下:

[插图]

这个回调函数有3个参数。

第1个参数formdata是数组对象。在这里,使用$.param()方法把它转化为字符串,得到如下这种格式:

[插图]

需要注意的是,当表单提交时,Form插件会以Ajax方式自动提交这些数据。

第2个参数jqForm是一个jQuery对象,它封装了表单的元素。

如果需要访问jqForm的DOM元素,可以把jqForm转换为DOM对象。

[插图]

第3个参数options就是options对象。前面已经声明了options对象里的一些属性,其他没有声明的,则会使用默认的属性。

在这个回调函数中,只要不返回 false,表单都将被允许提交;如果返回 false,则会阻止表单提交。可以利用这个特性,在表单提交之前验证数据(后面将详细讲解),如果不符合验证规则,则阻止表单提交。

  • success—提交后的回调函数

提交后的回调函数的代码如下:

[插图]

success有4个参数responseText,statusText,xhr和$form。其中responseText和statusText2个比较常用。

statusText只是一个返回状态,例如success、error等。

responseText 携带着服务器返回的数据内容。responseText 会根据设置的options 对象中的dataType属性来返回相应格式的内容。具体情况如下。

(1)对于缺省的HTML返回,回调函数的第1个参数是XMLHttpRequest对象的responseText属性。
(2)当 dataType 属性被设置为xml 时,回调函数的第1个参数是XMLHttpRequest 对象的responseXML属性。
例如声明服务器返回数据的类型为xml,然后以XML方式解析数据,代码如下:

[插图]

(3)当dataType属性被设置为json时,回调函数的第1个参数是从服务器返回的json数据对象。
例如声明服务器返回数据的类型为json,然后以json方式解析数据,代码如下:

[插图]

7.2.6 表单提交之前验证表单

大多数情况下,需要在表单提交前对表单元素的值进行一次验证,如果不符合验证规则,则阻止表单提交。

beforeSubmit会在表单提交前被调用。如果beforeSubmit返回false,则会阻止表单提交,利用这个特性,就可以轻松地完成验证表单元素的任务。

首先定义一个validate回调函数,把它设置为beforeSubmit的值。

[插图]

然后编写validate函数,它有3个参数:

[插图]

通过获取表单元素的值,对表单元素进行验证。Form 插件获取表单数据的方式有多种,下面讲解其中的3种方式。

  • 方式1:利用参数formData

参数formData是一个数组对象,其中的每个对象都有名称和值。其数据格式如下:

[插图]

由于是数组,因此可以根据循环来获取每个元素的值,然后判断元素的值是否符合验证规则(这里只判断元素是否为空),如果有一项不符合验证规则,就返回false,来阻止表单提交。代码如下:

[插图]

[插图]

图7-10 验证提示信息
  • 方式2:利用参数jqForm

不仅可以利用第1个参数formData来获取表单数据,而且可以用第2个参数jqForm来达到同样的效果。

参数jqForm是一个jQuery对象,它封装了表单的元素。如果需要访问jqForm的DOM元素,可以把jqForm转为DOM对象。

[插图]

然后通过form.name.value来获取用户名的值;通过form.address.value来获取地址的值。代码如下:

[插图]

  • 方式3:利用fieldValue()方法

fieldValue()方法会把匹配元素的值插入到数组中,然后返回这个数组。如果表单元素的值被判定无效,则数组为空,否则数组将包含一个或多个元素的值。由于返回的是一个数组,而不是jQuery对象,因此不能进行链式操作。

利用 fieldValue()方法,也能很容易地获取到表单元素的值。例如可以通过$('input[name=address]').fieldValue()来获取name为“address”的<input>元素的值的数组集合,然后通过数组下标来获取数组中对应的值。

代码如下:

[插图]

通过以上几个例子可以清楚地知道,使用jQuery Form插件能够很容易地把一个传统的表单提交方式改变为Ajax提交方式,没有比这更简单的方法了。

7.2.7 API

Form 插件拥有很多方法,这些方法可以帮助用户很容易地管理表单数据和表单提交。读者可以参考附录F的API介绍。

第7章 jQuery插件的使用和写法

插件(Plugin)也称为扩展(Extension),是一种遵循一定规范的应用程序接口编写出来的程序。

jQuery的易扩展性,吸引了来自全球的开发者来共同编写jQuery的插件。目前,已经有超过几千种的插件应用在全球不同类型的项目上。使用这些经过无数人检验和完善的优秀插件,可以帮助用户开发出稳定的应用系统,节约项目成本。

最新最全的插件可以从 jQuery 官方网站的插件板块中获取,网站地址为:http://plugins.jquery.com/ 。如图7-1所示,不仅可以在右上方或左中方的Search区域搜索jQuery插件,也可以在右中方的Categories区域,通过选择不同的类型来查找插件。

[插图]

图7-1 官网插件模块截图

下面介绍几个常用的jQuery插件,并对如何编写jQuery插件进行全面地讲解。

注意:因垃圾邮件、不规范的插件、数据备份、版本维护以及对目前插件站点功能的不满足等多种因素,jQuery官方已经将项目托管于GitHub。地址为:https://github.com/jquery/plugins.jquery.com。

7.1 jQuery表单验证插件—Validation

7.1.1 Validation简介

最常使用JavaScript的场合就是表单的验证,而jQuery作为一个优秀的JavaScript库,也提供了一个优秀的表单验证插件—Validation。Validation是历史最悠久的jQuery插件之一,经过了全球范围内不同项目的验证,并得到了许多 Web 开发者的好评。作为一个标准的验证方法库, Validation拥有如下特点。

  • 内置验证规则:拥有必填、数字、E-Mail、URL和信用卡号码等19类内置验证规则。
  • 自定义验证规则:可以很方便地自定义验证规则。
  • 简单强大的验证信息提示:默认了验证信息提示,并提供自定义覆盖默认提示信息的功能。
  • 实时验证:可以通过keyup或blur事件触发验证,而不仅仅在表单提交的时候验证。

Jörn Zaefferer设计了Validation插件,并从2006年7月开始一直在对该插件进行改善和维护。

7.1.2 下载地址

jQuery Validation插件的下载地址:

http://bassistance.de/jquery-plugins/jquery-plugin-validation/

在图7-2所示的界面中,不仅可以下载该插件,也可以查看所有历史版本的更新说明。在该页面还可以查看英文文档和演示例子等。

[插图]

图7-2 Validation插件页面截图

7.1.3 快速上手

先看一个简单的例子7-1-1,HTML和jQuery代码如下:

[插图]

上面代码完成了以下验证。
(1)对“姓名”的必填和长度至少是两位的验证。
(2)对“电子邮件”的必填和是否为E-mail格式的验证。
(3)对“网址”是否为url的验证。
(4)对“你的评论”的必填验证。

当用户单击“提交”按钮后,显示图7-3所示的效果。

[插图]

图7-3 快速上手例子

当用户在“姓名”对应的文本框中输入字符时,表单元素也会实时响应验证,产生图7-4所示的效果。

[插图]

图7-4 字段实时验证

当用户输入字符时,表单元素就会实时响应验证信息,而不是只在用户单击“提交”按钮后才出现。这样做的好处是极大地方便了用户,促使用户填写出符合格式的数据。

从例子中可以看到,只需完成以下几步操作,就可以将一个普通的表单改造为可以进行Validation验证的表单。

(1)引入jQuery库和Validation插件。

[插图]

(2)确定哪个表单需要被验证。

[插图]

(3)针对不同的字段,进行验证规则编码,设置字段相应的属性。

  • class=”required”为必须填写,minlength=”2”为最小长度为2。
  • class=”required email”为必须填写和内容需要符合E-mail格式。
  • class=”url”为url格式验证。

7.1.4 不同的验证写法

在上节的例子中,开发者必须把required、url和email写到class属性里,才能完成必填验证、url验证和E-mail验证;把minlength属性的值设置为2,才能完成最小长度为2的验证。虽然class和minlength属性都符合W3C规范,但对于开发者来说,时而将与验证相关的信息写在class属性里面,时而又写在minlength属性里面实在很麻烦。Validation充分考虑到了这一点,读者可以将所有的与验证相关的信息写到class属性中方便管理。为了实现这个功能,需要经过以下几个步骤。

(1)引入一个新的jQuery插件—jquery.metadata.js。

[插图]

注意:jquery.metadata.js是一个支持固定格式解析的jQuery插件,Validation插件将其很好地融合到验证规则编码中。通过下面的例子7-1-2,读者可以很容易地了解到需要掌握的格式,更加详细的metadata插件参见网址http://plugins.jquery.com/project/metadata 。

(2)改变调用的验证方法。

[插图]

改为

[插图]

(3)将验证规则全部编写到class属性中,例7-1-2的HTML代码如下:

[插图]

此时,本段代码的验证效果与前面的例子完全一致。

在上面两个例子中,验证规则都是通过设置一定的属性值来实现的,但验证行为和HTML结构并没有完全脱钩。下面介绍一种与HTML元素属性无直接关联,而是通过name属性来关联字段和验证规则的验证写法,这种方法可以实现行为与结构的分离。

首先,将字段中的class属性移除,此时的HTML代码并无其他多余的属性,例7-1-3的HTML代码如下:

[插图]

然后加入如下jQuery代码:

[插图]

运行代码后,验证效果与前面的例子也是完全一致的。本例中,具体编码步骤如下。
(1)在$("#commentForm").validate()方法中增加rules属性。
(2)通过每个字段的name属性值来匹配验证规则。
(3)定义验证规则:例如required: true,email: true,minlength: 2等。

7.1.5 验证信息

  • 国际化

Validation插件的验证信息默认语言为英文,如果要改成中文,只需要引入Validation提供的中文验证信息库即可,引入代码如下:

[插图]

引入语言库后,显示图7-5所示的验证效果。

[插图]

图7-5 中文提示信息

Validation插件也支持其他常用语言,读者可以自行引入相应的语言库进行配置。

  • 自定义验证信息

Validation插件可以很方便地自定义验证规则,用来代替千篇一律的默认验证信息,例如将例7-1-2中的字段提示信息的class值改成如下代码:

[插图]

运行代码后,显示图7-6所示的效果。

[插图]

图7-6 自定义验证信息
  • 自定义验证信息并美化

也许读者需要为验证提示信息加些漂亮的图片,这对于Validation插件来说,也是非常简单的事情。例如在例7-1-3中的jQuery代码中增加如下代码:

[插图]

在CSS代码中增加如下代码,以便和errorElement相关联。

[插图]

运行代码后,提示信息中就会包含错误提示图片,如图7-7所示效果。

[插图]

图7-7 错误提示

7.1.6 自定义验证规则

衡量一个表单验证插件是否优秀的重要标准是看它是否有良好的自定义验证规则。由于需求的多种多样,除提供的默认验证规则外,还需要自定义验证规则,满足业务需要。

在很多网站中,表单中都包括验证码,通过自定义验证规则,可以轻易地完成验证码的验证。

首先在上面例子的基础上,添加验证“验证码”的HTML代码,代码如下:

[插图]

为了实现验证“验证码”的功能,需要完成以下几个步骤。

(1)自定义一个验证规则。

jQuery代码:

[插图]

(2)调用该验证规则。

jQuery代码中的rules中加入valcode: { formula: “7+9” },其中”7+9”这个字符串可以通过其他手段获得,例如获取页面某个元素的text()或者通过Ajax来取得。这里为了简化就简单写成了”7+9”,如下面代码的加粗部分所示:

[插图]

运行代码后,该页面的验证显示如图7-8所示。

[插图]

图7-8 验证码验证

7.1.7 API

Validation插件的官方API地址为:
http://docs.jquery.com/Plugins/Validation
关于Validation插件的API内容,读者可以参考附录F。

7.2 jQuery表单插件—Form

6.9 小结

本章首先对Ajax进行了简介,并且介绍了Ajax的优势与不足,让读者充分了解到Ajax的适用范围。接下来介绍了Ajax的XMLHttpRequest对象,并展示了传统的Ajax程序的编写,然后系统地讲解了jQuery中的Ajax方法。在介绍了序列化元素和Ajax全局事件两个重要的概念后,讲解了一个稍微复杂的Ajax聊天室程序。

6.8 基于jQuery的Ajax聊天室程序

通过前面的介绍,相信读者已经对jQuery的Ajax有了较深的认识。下面,将讲解一个较为复杂的Ajax实例,可以帮助读者更好地掌握Ajax的精髓—一个基于Ajax无需刷新技术开发的聊天室程序,该程序允许多用户在网页上聊天,并且可以实时地更新信息。

通过前面的介绍,相信读者已经对jQuery的Ajax有了较深的认识。下面,将讲解一个较为复杂的Ajax实例,可以帮助读者更好地掌握Ajax的精髓—一个基于Ajax无需刷新技术开发的聊天室程序,该程序允许多用户在网页上聊天,并且可以实时地更新信息。

6.8.1 基本设想

首先设计聊天室的外观,如图6-15所示。

[插图]

图6-15 聊天室外观

6.8.2 设计数据库

这里使用MySql数据库来存储信息。

首先构建一个聊天信息表messages,它有4个字段,即消息编号(id)、姓名(user)、内容(msg)以及一个数字时间戳(time)。下面是创建该表的SQL代码:

[插图]

6.8.3 服务器端处理

服务器端主要用来处理用户提交的信息以及输出返回。

  • 首先需要在服务器端链接数据库。
  • 其次如果有用户提交新信息,则把信息插入数据库,同时删除旧的数据信息(保持数据库中只有10条信息)。
  • 最后从数据库中获取新的信息并以XML格式输出返回。

这里可以先模拟服务端输出的XML代码结构,XML文档代码如下:

[插图]

在这个XML结构中,不光只有消息的实体(包括作者及其聊天信息),还增加了一个“status”标签和一个“time”标签。其中“status”标签用来表示信息请求的状态,如果值为1,则表示新信息请求成功;如果值为2,则表示请求成功但没有新信息。“time”标签用来记录信息请求的时间,可以被用来读取该时间戳后用户提交的新数据。

6.8.4 客户端处理

在客户端需要做两项工作。

  • 首先提交用户聊天信息,然后处理服务器端返回的聊天信息,将信息实时呈现出来。
  • 每隔一定时间发起查询数据库中聊天记录的请求,然后处理服务端返回的聊天信息,将信息实时呈现出来。

(1)提交用户聊天信息

使用POST方式向服务器发送请求,将用户填写的姓名和内容等数据传递到服务器端,在服务器端处理后返回相应的XML数据,然后使用回调函数处理服务器端返回的这些数据,并将新信息追加到客户端的消息显示区中。

(2)浏览器每隔一定时间更新数据
增加一个定时器,并且每隔一定时间调用一次。然后使用回调函数处理服务器端返回的XML数据,并将新信息追加到客户端的消息显示区中。

由于上面的两项工作都需要对XML文档进行解析,然后追加到信息显示区,因此可以将此操作进行封装,以便于重复利用。在设计该XML文档操作函数时,应注意通过状态(“status”标签)和时间戳(“time”标签)来控制获取聊天信息。

6.8.5 客户端代码

1.客户端HTML代码

首先建立一个HTML页面。从前面的外观设计可以知道页面需要一个外围<div>、一个消息段落(用来显示聊天信息)、姓名文本框、消息文本、提交按钮的表单和一个加载信息时的提示。HTML代码如下:

[插图]

当用户第1次进入聊天室的时候,显示效果如图6-16所示。

[插图]

图6-16 初始化页面效果

2.客户端jQuery代码

首先,需要设置当前消息的时间戳为0,并且调用函数来加载数据库已有的聊天消息,代码如下:

[插图]

然后,为表单添加一个submit事件,代码如下:

[插图]

在submit事件函数中,可以使用jQuery的$.post()方法来发送一个POST请求,把要传递的数据都放入第2个参数中,用{ }包裹,代码如下:

[插图]

接下来,如何响应返回的XML呢?为了使代码能被重用,这里创建一个处理XML的函数并且调用该函数(在updateMsg()方法中,也要用到这个解析XML的函数)。函数如下:

[插图]

addMessages()函数里的具体内容将在后边实现。

现在就可以列出表单提交的全部代码了,代码如下:

[插图]

在表单提交事件的最后一行添加了“return false;”语句,可以用来阻止浏览器提交表单。

现在再看addMessages()函数,它是用来处理XML响应信息的。前面讲解过,jQuery遍历XML文档与遍历DOM一样。使用XML文档中的状态码,其代码如下:

[插图]

上段代码中使用$(“status”,xml)方法来通知jQuery去XML文档中寻找“status”标签。如果状态代码为2,则表示完成了请求但没有新信息需要添加到该客户端的消息显示区中,因此使用“return;”语句终止函数调用。如果状态代码不为2,则继续往下执行。

接下来需要为XML的时间戳设定新的值,用来传递给后台去查询新的数据。获取时间戳的代码如下:

[插图]

然后使用$.each()函数将XML文档里的数据遍历出来。在示例中,需要显示到客户端消息显示区的元素就是服务器端返回的每一个“message”标签的实例,每个实例代表一条要显示的消息。以下代码展示如何遍历数据:

[插图]

得到了所需的数据之后,就可以将其追加到消息显示区里。消息显示窗体的id 为“messagewindow”,因此可以使用$(“#messagewindow”)来选择到它并且使用prepend()方法来追加数据,代码如下:

[插图]

将它们整合后,addMessages(xml)函数的代码如下:

[插图]

最后,只剩下刚开始调用的函数 updateMsg()还未完成。该函数的功能是到服务器查询新信息,并且调用addMessages()函数来响应返回的XML文档,同时需要设置一个间隔时间,让聊天窗口自动更新。要开始做这些工作,只需要向服务器提交一个时间戳,引用这个$.post()调用即可,代码如下:

[插图]

在回调函数里,首先应该移除loading消息,可以在这个元素上调用remove()方法,代码如下:

[插图]

然后,在回调函数中将接受到的XML文档对象传递给addMessages()函数,代码如下:

[插图]

最后调用JavaScript的setTimeout()方法来每隔一定时间执行updateMsg()函数。

updateMsg()函数的代码如下:

[插图]

6.8.6 整合代码

[插图]

聊天界面如图6-17所示。

[插图]

图6-17 最终的聊天室程序

正如读者所看到的,仅用了少量的jQuery代码,就实现了一个完整的基于Ajax的Web聊天室应用程序。用jQuery可以如此简单的实现一个复杂的Ajax应用,不得不令人叹服。

6.9 小结

6.7 jQuery中的Ajax全局事件

jQuery简化Ajax操作不仅体现在调用Ajax方法和处理响应方面,而且还体现在对调用Ajax方法的过程中的HTTP请求的控制。通过jQuery提供的一些自定义全局函数,能够为各种与Ajax相关的事件注册回调函数。例如当 Ajax 请求开始时,会触发 ajaxStart()方法的回调函数;当 Ajax请求结束时,会触发 ajaxStop()方法的回调函数。这些方法都是全局的方法,因此无论创建它们的代码位于何处,只要有Ajax请求发生时,就会触发它们。在前面例子中,远程读取Flickr.com网站的图片速度可能会比较慢,如果在加载的过程中,不给用户提供一些提示和反馈信息,很容易让用户误认为按钮单击无用,使用户对网站失去信心。

此时,就需要为网页添加一个提示信息,常用的提示信息是“加载中…”,代码如下:

[插图]

然后用CSS控制元素隐藏,当Ajax请求开始的时候,将此元素显示,用来提示用户Ajax请求正在进行。当Ajax请求结束后,将此元素隐藏。代码如下:

[插图]

这样一来,在 Ajax 请求过程中,只要图片还未加载完毕,就会一直显示“加载中…”的提示信息,看似很简单的一个改进,却将极大地改善用户的体验。效果如图6-13所示。

[插图]

图6-13 显示“加载中...”的提示信息

如果在此页面中的其他地方也使用 Ajax,该提示信息仍然有效,因为它是全局的。如图6-14所示。

[插图]

图6-14 demo2也使用同一个提示信息

jQuery的Ajax全局事件中还有几个方法,也可以在使用Ajax方法的过程中为其带来方便。如表6-4所示。

表6-4 另外几个方法

[插图]

注意:1,如果想使某个 Ajax 请求不受全局方法的影响,那么可以在使用$.ajax(options)方法时,将参数中的global设置为false,jQuery代码如下:[插图]

具体原因请查看:http://bugs.jquery.com/ticket/8338

6.5 jQuery中的Ajax

jQuery对Ajax操作进行了封装,在jQuery中$.ajax()方法属于最底层的方法,第2层是load()、$.get()$.post()方法,第3层是$.getScript()$.getJSON()方法。首先介绍第2层的方法,因为其使用频率很高。

6.5.1 load()方法

1.载入HTML文档

load()方法是jQuery中最为简单和常用的Ajax方法,能载入远程HTML代码并插入DOM中。它的结构为:

[插图]

load()方法参数解释如表6-1所示。

表6-1 load()方法参数解释

[插图]

首先构建一个被load()方法加载并追加到页面中的HTML文件,名字为test.html,HTML代码如下:

[插图]

然后新建一个空白页面,在上面添加两个元素:<button>按钮用来触发Ajax事件,id为“resText”的元素用来显示追加的HTML内容。HTML代码如下:

[插图]

接下来就可以开始编写jQuery代码了。等DOM元素加载完毕后,通过单击id为“send”的按钮来调用load()方法,然后将test.html的内容加载到id为“resText”的元素里。

jQuery代码如下:

[插图]

当按钮被单击后,出现图6-3所示的界面。

[插图]

图6-3 load()方法调用成功

显然,load()方法完成了原本很繁琐的工作。开发人员只需要使用jQuery选择器为HTML片段指定目标位置,然后将要加载的文件的URL 作为参数传递给 load()方法即可。当单击按钮后, test.html页面的HTML内容就会被加载并插入主页面<divid="resText"></div>的元素中。

注意:test.html页面里并没有添加样式,但现在加载的内容有样式了。这些样式是在主页面中添加的,即主页面相应的样式会立即应用到新加载的内容上。

2.筛选载入的HTML文档

上个例子是将 test.html 页面中的内容都加载到 id 为“resText”的元素里。如果只需要加载test.html页面内的某些元素,那么可以使用load()方法的URL参数来达到目的。通过为URL参数指定选择符,就可以很方便地从加载过来的HTML文档里筛选出所需要的内容。

load()方法的URL参数的语法结构为:”url selector”。注意,URL和选择器之间有一个空格。

例如只需要加载test.html页面中class为“para”的内容,可以使用如下代码来完成:

[插图]

运行效果如图6-4所示。

[插图]

图6-4 用load()方法加载一部分HTML元素

3.传递方式

load()方法的传递方式根据参数data来自动指定。如果没有参数传递,则采用GET方式传递;反之,则会自动转换为POST方式。关于GET和POST传递方式的区别,将在后面进行讲解。

[插图]

4.回调参数

对于必须在加载完成后才能继续的操作,load()方法提供了回调函数(callback),该函数有 3个参数,分别代表请求返回的内容、请求状态和XMLHttpRequest对象,jQuery代码如下:

[插图]

注意:在load()方法中,无论Ajax请求是否成功,只要当请求完成(complete)后,回调函数(callback)就被触发。对应下面将介绍的$.ajax()方法中的complete回调函数。

6.5.2 $.get()方法和$.post()方法

load()方法通常用来从 Web 服务器上获取静态的数据文件,然而这并不能体现Ajax的全部价值。在项目中,如果需要传递一些参数给服务器中的页面,那么可以使用$.get()或者$.post()方法(或者是后面要讲解的$.ajax()方法)。

注意:`$.get()`和`$.post(`)`方法是jQuery中的全局函数,而在此之前讲的jQuery方法都是对jQuery对象进行操作的。

1.$.get()方法

$.get()方法使用GET方式来进行异步请求。

它的结构为:

[插图]

$.get()方法参数解释如表6-2所示。

表6-2 $.get()方法参数解释

[插图]

下面是一个评论页面的HTML代码,通过该段代码来介绍$.get()方法的使用。

[插图]

本段代码将生成图6-5所示的页面。

[插图]

图6-5 评论初始化页面

将姓名和内容填写好后,就可以准备提交评论了。如图6-6所示。

[插图]

图6-6 填写好数据

(1)使用参数

首先,需要确定请求页面的URL地址。代码如下:

[插图]

然后,在提交之前,需要获取“姓名”和“内容”的值作为data参数传递给后台。

代码如下:

[插图]

如果服务器端接收到传递的data 数据并成功返回,那么就可以通过回调函数将返回的数据显示到页面上。

$.get()方法的回调函数只有两个参数,代码如下:

[插图]

data 参数代表请求返回的内容,textStatus 参数代表请求状态,而且回调函数只有当数据成功返回(success)后才被调用,这点与load()方法不一样。

(2)数据格式

服务器返回的数据格式可以有多种,它们都可以完成同样的任务。以下是几种返回格式的对比。

  • HTML片段

由于服务器端返回的数据格式是HTML片段,因此并不需要经过处理就可以将新的HTML数据插入到主页面中。jQuery代码如下:

[插图]

HTML 片段实现起来只需要很少的工作量,但这种固定的数据结构并不一定能够在其他的Web应用程序中得到重用。

  • XML文档

由于服务器端返回的数据格式是XML文档,因此需要对返回的数据进行处理,前面的章节已经介绍过jQuery强大的DOM处理能力,处理XML文档与处理HTML文档一样,也可以使用常规的attr()、find()、filter()以及其他方法。jQuery代码如下:

返回数据格式为XML文档的过程实现起来比HTML片段要稍微复杂些,但XML文档的可移植性是其他数据格式无法比拟的,因此以这种格式提供的数据的重用性将极大提高。例如 del.icio.us (http://del.icio.us),Flickr(http://flickr.com)和某些开放平台都是以XML格式输出数据,读者可以利用它们提供的API,将获得的内容整合到自己的网站中(Mashup应用)。不过,XML文档体积相对较大,与其他文件格式相比,解析和操作它们的速度要慢一些。

[插图]

注意:由于期待服务器端返回的数据格式是XML文档,因此需要在服务端设置Content-Type类型,代码如下:[插图]
  • JSON文件

之所以会出现这种数据格式的文件,很大程度上是因为XML 文档体积大和难以解析。JSON文件和XML文档一样,也可以方便的被重用。而且,JSON文件非常简洁,也容易阅读。想了解更多的JSON文档知识,可以访问http://json.org/ 网址。

由于服务器端返回的数据格式是JSON文件,因此需要对返回的数据进行处理之后,才可以将新的HTML数据添加到主页面中。jQuery代码如下:

[插图]

在上面的代码中,将$.get()方法的第4个参数(type)设置为“json”来代表期待服务器端返回的数据格式。

注意:(1)在不远的将来,新版的JavaScript中XML将会和JSON一样容易解析,相信到时候通用且容易解析的XML将会成为主流的数据交换格式。不过在它到来之前,JSON依然有很强的生命力。(2)JSON的格式非常严格,构建的JSON文件必须完整无误,任何一个括号的不匹配或者缺少逗号,都会导致页面上的脚本终止运行,甚至还会带来其他更加严重的负面影响。比如,我们返回的数据都必须要有双引号,必须是:{ "username" :"张三" },而不能是:{ username: "张三" }。

以上3种返回方式都可以达到图6-7所示的效果。

[插图]

图6-7 将返回的数据添加到页面上

通过对3种数据格式的优缺点进行分析,可以得知在不需要与其他应用程序共享数据的时候,使用HTML片段来提供返回数据一般来说是最简单的;如果数据需要重用,那么 JSON文件是不错的选择,它在性能和文件大小方面具有优势;而当远程应用程序未知时,XML 文档是明智的选择,它是 Web 服务领域的“世界语”。具体选择哪种数据格式,并没有严格的规定,读者可以根据需求来选择最适合的返回格式来进行开发。

2.$.post()方法

它与$.get()方法的结构和使用方式都相同,不过它们之间仍然有以下区别。

  • GET请求会将参数跟在URL后进行传递,而POST请求则是作为HTTP消息的实体内容发送给Web服务器。当然,在Ajax请求中,这种区别对用户是不可见的。
  • GET方式对传输的数据有大小限制(通常不能大于2KB),而使用POST方式传递的数据量要比GET方式大得多(理论上不受限制)。
  • GET 方式请求的数据会被浏览器缓存起来,因此其他人就可以从浏览器的历史记录中读取到这些数据,例如账号和密码等。在某种情况下,GET方式会带来严重的安全性问题,而POST方式相对来说就可以避免这些问题。
  • GET方式和POST方式传递的数据在服务器端的获取也不相同。在PHP中,GET方式的数据可以用$_GET[]获取,而 POST 方式可以用$_POST[]获取。两种方式都可以用$_REQUEST[]来获取。

由于 POST和GET 方式提交的所有数据都可以通过$_REQUEST[]来获取,因此只需要改变jQuery函数,就可以将程序在GET请求和POST请求之间切换。代码如下:

[插图]

另外,当load()方法带有参数传递时,会使用POST方式发送请求。因此也可以使用load()方法来完成同样的功能。代码如下:

[插图]

上面使用load()、$.get()$.post()方法完成了一些常规的Ajax程序,如果还需要编写一些复杂的Ajax程序,那么就要用到jQuery中的$.ajax()方法。$.ajax()方法不仅能实现与load()、$.get()$.post()方法同样的功能,而且还可以设定beforeSend(提交前回调函数)、error(请求失败后处理)、success(请求成功后处理)以及complete(请求完成后处理)回调函数,通过这些回调函数,可以给用户更多的Ajax提示信息。另外,还有一些参数,可以设置Ajax请求的超时时间或者页面的“最后更改”状态等。关于$.ajax()方法将在后面的章节中进行讲解。

6.5.3 $.getScript()方法和$.getJson()方法

1.$.getScript()

有时候,在页面初次加载时就取得所需的全部JavaScript文件是完全没有必要的。虽然可以在需要哪个JavaScript文件时,动态地创建<script>标签,jQuery代码如下:

[插图]

或者

[插图]

但这种方式并不理想。为此,jQuery 提供了$.getScript()方法来直接加载.js文件,与加载一个HTML片段一样简单方便,并且不需要对JavaScript文件进行处理,JavaScript文件会自动执行。

jQuery代码如下:

[插图]

当“加载”按钮被单击后,出现如图6-8所示的效果。

[插图]

图6-8 $.getScript('test.js')方法调用成功

与其他 Ajax 方法一样,$.getScript()方法也有回调函数,它会在 JavaScript文件成功载入后运行。例如想载入jQuery官方颜色动画插件(jquery.color.js),成功后给元素绑定颜色变化动画,就可以用到$.getScript()方法的回调函数。代码如下:

[插图]

当jquery.color.js动画插件加载完毕后,单击id为“go”按钮时,class为block的元素就有了颜色动画变化。

2.$.getJSON()

$.getJSON()方法用于加载JSON文件,与$.getScript()方法的用法相同。

jQuery代码如下:

[插图]

当单击“加载”按钮后,网页上看不到任何效果。虽然函数加载了JSON文件,但是并没有告诉JavaScript对返回的数据如何处理。为此,jQuery提供了回调函数,在回调函数里处理返回的数据。代码如下:

[插图]

可以在函数中通过 data 变量来遍历相应的数据,也可以使用迭代方式为每个项构建相应的HTML 代码。虽然在这里可以使用传统的for 循环来实现,但既然是讲解jQuery,那么还是使用jQuery里的方法。jQuery提供了一个通用的遍历方法$.each(),可以用于遍历对象和数组。

$.each()函数不同于jQuery对象的each()方法,它是一个全局函数,不操作jQuery对象,而是以一个数组或者对象作为第1个参数,以一个回调函数作为第2个参数。回调函数拥有两个参数:第1个为对象的成员或数组的索引,第2个为对应变量或内容。代码如下:

[插图]

在上面的代码中,当返回数据成功后,首先清空 id 为“resText”的元素的内容,以便重新构造新的HTML,然后通过$.each()循环函数依次遍历每个项,并将遍历出来的内容构建成HTML代码拼接起来,最后将构建好的HTML添加到id为“resText”的元素中。

当“加载”按钮被单击后,出现如图6-9所示的效果。

[插图]

图6-9 $.getJSON('test.json')函数执行成功

不仅如此,还能通过使用JSONP形式的回调函数来加载其他网站的JSON数据,例如从图片网站(http://Flickr.com)搜索汽车类别的4张最新图片。代码如下:

[插图]

上面的代码中再次用到全局函数$.each()来遍历数据,因为只需要 4 张图片,所以当 i=3的时候就需要退出循环。在$.each()函数中,如果需要退出each循环,只要返回false即可。

当“加载”按钮被单击后,从Flickr网站加载的4张最新的汽车图片就会被添加到页面中。效果如图6-10所示。

[插图]

图6-10 加载Flickr网站的图片
注意:(1)jQuery 将自动把 URL 里的回调函数,例如“url?callback=?”中的后一个“?”替换为正确的函数名,以执行回调函数。(2)JSONP(JSON with Padding)是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过JavaScript Callback的形式实现跨域访问。由于JSON只是一种含有简单括号结构的纯文本,因此许多通道都可以交换JSON消息。而由于同源策略的限制,开发人员不能在与外部服务器进行通信的时候使用 XMLHttpRequest。而 JSONP是一种可以绕过同源策略的方法,即通过使用JSON与<script>标记相结合的方法,从服务器端直接返回可执行的JavaScript函数调用或者JavaScript对象。目前JSONP已经成为各大公司的Web应用程序跨域首选,例如Youtube GData、GoogleSocial Graph、Digg、豆瓣、Del.icio.us等。

6.5.4 $.ajax()方法

$.ajax()方法是jQuery最底层的Ajax实现。

它的结构为:

[插图]

该方法只有1个参数,但在这个对象里包含了$.ajax()方法所需要的请求设置以及回调函数等信息,参数以key/value的形式存在,所有参数都是可选的,常用参数如表6-3所示。

表6-3 $.ajax()方法常用参数解释

[插图]

如果需要使用$.ajax()方法来进行 Ajax 开发,那么上面这些常用的参数都必须了解。此外,$.ajax()方法还有其他参数,读者可以参考附录D的具体介绍。

前面用到的$.load()$.get()$.post()$.getScript()$.getJSON()这些方法,都是基于$.ajax()方法构建的,$.ajax()方法是jQuery最底层的Ajax实现,因此可以用它来代替前面的所有方法。

例如,可以使用下面的jQuery代码代替$.getScript()方法:

[插图]

再例如,可以使用以下jQuery代码来代替$.getJSON()方法:

[插图]

6.6 序列化元素

1.serialize()方法

做项目的过程中,表单是必不可少的,经常用来提供数据,例如注册、登录等。常规的方法是使表单提交到另一个页面,整个浏览器都会被刷新,而使用Ajax技术则能够异步地提交表单,并将服务器返回的数据显示在当前页面中。

前面在讲解$.get()和$.post()方法的时候,表单的HMTL代码如下:

[插图]

为了获取姓名和内容,必须将字段的值逐个添加到data参数中。代码如下:

[插图]

这种方式在只有少量字段的表单中,勉强还可以使用,但如果表单元素越来越复杂,使用这种方式在增大工作量的同时也使表单缺乏弹性。jQuery 为这一常用的操作提供了一个简化的方法—serialize()。与jQuery中其他方法一样,serialize()方法也是作用于一个jQuery对象,它能够将DOM元素内容序列化为字符串,用于Ajax请求。通过使用serlialize()方法,可以把刚才的jQuery代码改为如下:

[插图]

当单击“提交”按钮后,也能达到同样的效果。如图6-11所示。

[插图]

图6-11 使用serialize()方法

需要注意的是,$.get()方法中data参数不仅可以使用映射方式,如以下jQuery代码:

[插图]

也可以使用字符串方式,如以下jQuery代码:

[插图]

用字符串方式时,需要注意对字符编码(中文问题),如果不希望编码带来麻烦,可以使用serialize()方法,它会自动编码。

因为serialize()方法作用于jQuery对象,所以不光只有表单能使用它,其他选择器选取的元素也都能使用它,如以下jQuery代码:

[插图]

把复选框和单选框的值序列化为字符串形式,只会将选中的值序列化。

2.serializeArray()方法

在jQuery中还有一个与serialize()类似的方法—serializeArray(),该方法不是返回字符串,而是将DOM元素序列化后,返回JSON格式的数据。jQuery代码如下:

[插图]

通过console.log()方法输出fields对象,然后在Firebug中查看该对象,如图6-12所示。

[插图]

图6-12 用Firebug查看对象

既然是一个对象,那么就可以使用$.each()函数对数据进行迭代输出。代码如下:

[插图]

3.$.param()方法

它是serialize()方法的核心,用来对一个数组或对象按照key/value进行序列化。

比如将一个普通的对象序列化:

[插图]

6.4 编写第1个Ajax例子

在正式接触jQuery的Ajax操作之前,先看一个用传统的JavaScript实现的Ajax例子。例子描述:单击一个按钮,然后通过传统的JavaScript的Ajax的方式从服务器端取回一个“Hello Ajax!”的字符串并显示在页面上。

首先在前台页面中书写HTML代码,代码如下:

[插图]

<button>按钮用来触发Ajax,id为“resText”的元素用来显示从服务器返回的HTML文本。

接下来的任务就是完成Ajax()函数,实现步骤如下。
(1)定义一个函数,通过该函数来异步获取信息,代码如下:

[插图]

(2)声明一个空对象用来装入XMLHttpRequest对象,代码如下:

[插图]

(3)给XMLHttpRequest对象赋值,代码如下:

[插图]

IE 5、IE 6是以 ActiveXObject的方式引入 XMLHttpRequest 对象的,而其他浏览器的XML HttpRequest对象是window的子对象。

(4)实例化成功后,使用open()方法初始化XMLHttpRequest对象,指定HTTP方法和要使用的服务器URL,代码如下:

[插图]

默认情况下,使用XMLHttpRequest对象发送的HTTP请求是异步进行的,但是可以显式地把async参数设置为true,如上面代码所示。

(5)因为要做一个异步调用,所以需要注册一个XMLHttpRequest对象将调用的回调事件处理器当它的readyState值改变时调用。当readyState值被改变时,会激发一个readystatechange事件,可以使用onreadystatechange属性来注册该回调事件处理器,代码如下:

[插图]

(6)使用send()方法发送该请求,因为这个请求使用的是HTTP的GET方式,所以可以在不指定参数或使用null参数的情况下调用send()方法,代码如下:

[插图]

当请求状态改变时,XMLHttpRequest对象调用onreadystatechange属性注册的事件处理器。因此,在处理该响应之前,事件处理器应该首先检查readyState的值和HTTP状态。当请求完成加载(readyState值为4)并且响应已经成功(HTTP状态值为200)时,就可以调用一个JavaScript函数来处理该响应内容,代码如下:

[插图]

最后,如果单击“Ajax提交”按钮后发现网页上出现了“Hello Ajax!”,那么就完成了第1个Ajax调用。如图6-2所示。

[插图]

图6-2 第1个Ajax示例

以上就是实现XMLHttpRequest对象使用的所有细节,它不必将Web页面的所有内容都发送到服务器,而是按需发送。使用JavaScript启动一个请求并处理相应的返回值,然后使用浏览器的DOM方法更新页面中的数据。显然,这种无刷新的模式能给网站带来更好的用户体验。但是XMLHttpRequest对象的很多属性和方法,对于想快速入门Ajax的人来说,似乎并不是个容易的过程。

幸运的是,jQuery提供了一些日常开发中需要的快捷操作,例如load、ajax、get和post等,使用jQuery开发Ajax将变得极其简单。这样开发人员就可以将程序开发集中在业务和用户体验上,而不需要理会那些繁琐的XMLHttpRequest对象。下面开始介绍jQuery中的Ajax。

6.2 Ajax的XMLHttpRequest对象

Ajax的核心是XMLHttpRequest对象,它是Ajax实现的关键—发送异步请求、接收响应及执行回调都是通过它来完成的。XMLHttpRequest 对象最早是在Microsoft Internet Explorer 5.0 ActiveX 组件中被引入的,之后各大浏览器厂商都以 JavaScript 内置对象的方式来实现XMLHttpRequest 对象。虽然大家对它的实现方式有所区别,但是绝大多数浏览器都提供了类似的属性和方法,而且在实际脚本编写方法上的区别也不大,实现得到的效果也基本相同。目前 W3C组织正致力于制定一个各浏览器厂商可以统一遵照执行的XMLHttpRequest 对象标准,用来推进Ajax技术的推广与发展。

XMLHttpRequest对象提供了一个相对精简易用的API,本书在附录C中进行了详细介绍,读者可以自行查看。

6.3 安装Web环境—AppServ

由于讲解后面的Ajax 方法需要与 Web 服务器端进行交互,因此这里将引用一个工具包—AppServ,它是PHP网页架站工具组合包,能够帮助初学者快速完成网页架站。AppServ所包含的软件有Apache、Apache Monitor、PHP、MySQL、PHP-Nuk和phpMy Admin。

1.下载AppServ

下载地址为:http://www.appservnetwork.com

2.安装AppServ

安装AppServ非常简单,只要连续轻松地单击“Next”按钮,输入网址、电子邮箱、密码等常用信息即可。端口默认为80,当然也可以在安装时进行修改。

3.配置示例程序

将本书提供的示例程序复制到安装好后的AppServ\www文件夹中,然后在地址栏输入“http://localhost/Ch6/php/ ”,即可显示图6-1所示的页面。

[插图]

图6-1 AppServ下的Ajax示例

单击相应文件夹,选定HTML页面,即可运行相应的Ajax示例。

注意:本书还提供了另外两种主流语言JSP和ASP编写的对应的示例程序,读者可以自行配置相应环境进行测试和学习。

第6章 jQuery与Ajax的应用

Ajax全称为“Asynchronous JavaScript and XML”(异步JavaScript和XML),它并不是指一种单一的技术,而是有机地利用了一系列交互式网页应用相关的技术所形成的结合体。它的出现,揭开了无刷新更新页面的新时代,并有代替传统的Web 方式和通过隐藏的框架来进行异步提交的趋势,是Web开发应用的一个里程碑。

6.1 Ajax的优势和不足

6.1.1 Ajax的优势

1.不需要插件支持

Ajax不需要任何浏览器插件,就可以被绝大多数主流浏览器所支持,用户只需要允许JavaScript在浏览器上执行即可。

2.优秀的用户体验

这是Ajax技术的最大优点,能在不刷新整个页面的前提下更新数据,这使得Web应用程序能更为迅速地回应用户的操作。

3.提高Web程序的性能

与传统模式相比,Ajax 模式在性能上的最大区别就在于传输数据的方式,在传统模式中,数据提交是通过表单(Form)来实现的,而数据获取是靠全页面刷新来重新获取整页的内容。Ajax模式只是通过XMLHttpRequest对象向服务器端提交希望提交的数据,即按需发送。

4.减轻服务器和带宽的负担

Ajax的工作原理相当于在用户和服务器之间加了—个中间层,使用户操作与服务器响应异步化。它在客户端创建Ajax引擎,把传统方式下的一些服务器负担的工作转移到客户端,便于客户端资源来处理,减轻服务器和带宽的负担。

6.1.2 Ajax的不足

世界上并没有完美的事物,同样Ajax也并不是一项非常完美的技术。Ajax主要有以下几点不足之处。

1.浏览器对XMLHttpRequest对象的支持度不足

Ajax的不足之一首先来自于浏览器。Internet Explorer 在 5.0 及以后的版本才支持 XML HttpRequest对象(现阶段大部分客户端上的IE浏览器是IE 6及以上),Mozilla、Netscape等浏览器支持XMLHttpRequest则更在其后。为了使得Ajax应用能在各个浏览器中正常运行,程序员必须花费大量的精力编码以兼顾各个浏览器之间的差别,来让Ajax应用能够很好地兼容各个浏览器。这使得Ajax开发的难度比普通的Web开发高出很多,许多程序员因此对Ajax望而生畏。

2.破坏浏览器前进、“后退”按钮的正常功能

在传统的网页中,用户经常会习惯性的使用浏览器自带的“前进”和“后退”按钮,然而Ajax改变了此Web浏览习惯。在Ajax中“前进”和“后退”按钮的功能都会失效,虽然可以通过一定的方法(添加锚点)来使得用户可以使用“前进”和“后退”按钮,但相对于传统的方式却麻烦了很多,对于大多数程序员来说宁可放弃前进、后退的功能,也不愿意在繁琐的逻辑中去处理该问题。然而,对于用户来说,他们经常会碰到这种情况,当单击一个按钮触发一个Ajax交互后又觉得不想这样做,接着就去习惯性地单击“后退”按钮,结果发生了最不愿意看到的结果,浏览器后退到了先前的一个页面,通过Ajax交互得到的内容完全消失了。

3.对搜索引擎的支持的不足

对于搜索引擎的支持也是Ajax的一项缺憾。通常搜索引擎都是通过爬虫程序来对互联网上的数以亿计的海量数据来进行搜索整理的,然而爬虫程序现在还不能理解那些奇怪的JavaScript代码和因此引起的页面内容的变化,这使得应用Ajax的站点在网络推广上相对于传统站点明显处于劣势。

4.开发和调试工具的缺乏

JavaScript是Ajax的重要组成部分,在目前,由于缺少很好的JavaScript开发和调试工具,使很多Web开发者对JavaScript望而生畏,这对于编写Ajax代码就更加困难了。同时,目前许多Web开发者已经习惯使用可视化的工具,对亲自动手编写代码有畏惧感,这也在一定程度上影响了大家对Ajax的应用。